xsl-list
[Top] [All Lists]

Re: [xsl] Identifying unique attribute values in nested sibling elements

2011-09-29 14:31:41
Ken,
Thanks,
You are quite right: my problem is that I am a very good C++ programmer but a very mediocre (if not incompetent) XPath programmer. I have a great deal of difficulty explaining what I want to do in terms of nodes (because I do tend to think in terms of C++ strings rather than nodes).

My stylesheet produces an XHTML page for every <Stamp> element within a <Set> and a different kind of XHMTL page for each of the <Formats> elements. The source XML is quite complicated and the construction of the <Formats> XHTML pages are not straight-forward. Information for each (there are five additional formats beyond the "se-tenant" one) must be gathered across different <Stamp> lines within a <Set>. These scenarios change slightly for each type of <Formats> element. I can now see that if I work with nodes, life would be simpler. I'll try to work with and understand your code. It would be very liberating for me to be able to grasp nodes as the preferred computational form.

Thank you for your kindness in explaining why I am having a problem. You have always been most helpful and insightful -- I have never seen your comments as anything but that.
Mark

-----Original Message----- From: G. Ken Holman
Sent: Thursday, September 29, 2011 11:52 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Identifying unique attribute values in nested sibling elements

At 2011-09-29 11:37 -0700, Mark wrote:
...
This string is exactly what I wanted earlier and was unable to describe acurately.

Apparently you don't want strings, you now say you want nodes.

My problem: I now need to tokenize these strings (or break them into usable substrings) so that I can produce the output XHTML .

If your output is nodes (serialized XHTML) then why bother going
first to strings and then back again?  My solution kept the nodes intact.

I only need to pay attention to the digits on the left of '=' and the unit-name (kc-value, h-value) on its right. The substring (token) separator is ';'

"3.60=kc-value;" is transformed to: <a "href="../aval/3-60.htm">3.60kc</a>
" =h-value;" has no digits in front of the '=' and thus must be ignored (the needed information was actually absorbed by the previous token)
"5=kc-value;"     is transformed to:  <a href="../aval/5.htm">5kc</a>
"6=kc-value;"    is transformed to:  <a href="../aval/6.htm">6kc</a>
"8=kc-value;"   is transformed to: <a href="../aval/8.htm">8kc</a>

Can you show me how to do this?

Below I've modified my earlier solution to give you what you ask for
for the kc-value= attributes ... you don't say what you want for the
other attributes so I elided that code.  It could be made more
compact, but I left it a bit open so you could adapt it for your
needs.  Perhaps you want links for the other attributes.  And I don't
know where the duplicates come into play, so I took that code out as well.

I just don't see why you are doing the heavy lifting of going to a
string just to get more heavy lifting of going back to nodes.  I
suggest you stick with the nodes.  Not only are you not making extra
work for yourself, but there is now no opportunity to introduce bugs
or worry about accidental lexical duplications in the strings
triggering unexpected regex results.

I hope this helps.

. . . . . . . . . . Ken

p.s. please forgive me if the above sounds critical, I'm not
intending it as such, I'm just asking the questions aloud so that you
can see the benefit of avoiding the unneeded processing you are introducing

p.p.s. note that I've seen such kinds of elaborate string-based
solutions in the classroom from students who are programmers used to
dealing with strings ... when working with XML it is sometimes (most
times?) far easier to work with nodes and not strings, and getting
that across to the students is an important learning outcome of the class

~/t/ftemp $ xslt2 mark.xml mark.xsl
<?xml version="1.0" encoding="UTF-8"?><html>
   <head>Mark's test</head>
   <body>
      <a href="../aval/14.htm">14kc</a>
      <a href="../aval/18.htm">18kc</a>
      <a href="../aval/18.htm">18kc</a>
      <a href="../aval/0.htm">0kc</a>
   </body>
</html>~/t/ftemp $ cat mark.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:m="urn:X-Mark" exclude-result-prefixes="m"
  version="2.0">
  <xsl:output method="xhtml"/>

  <!--compose a string of attribute names and their values;
      avoid the possibility of co-incidental string values;-->
  <xsl:function name="m:attrs">
    <xsl:param name="this"/>
    <xsl:value-of>
      <xsl:for-each select="$this/@*">
        <xsl:sort select="name(.)"/>
        <xsl:value-of select="name(.),'&#xfdd0;',.,'&#xfdd0;'"/>
      </xsl:for-each>
    </xsl:value-of>
  </xsl:function>

  <!--common reporting-->
  <xsl:function name="m:report">
    <xsl:param name="Stamp"/>
    <xsl:for-each select="$Stamp">
      <xsl:for-each select="Value/@kc-value">
        <a href="../aval/{.}.htm">
          <xsl:value-of select="."/>kc<xsl:text/>
        </a>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:function>

  <xsl:template match="/">
    <html>
      <head>Mark's test</head>
      <body>
        <xsl:for-each-group select="Stamp[Formats/@se-tenant=1]"
                            group-by="m:attrs(Value)">
          <xsl:copy-of select="m:report(.)"/>
        </xsl:for-each-group>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>
~/t/ftemp $ cat mark.xml
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers  pofis-number="1"/>
     <Value kc-value="14"/>
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="2"/>
     <Value kc-value="18"/>
     <Formats se-tenant="1"/>
</Stamp>
..... <!--possibly other unrelated stamp elements-->
<Stamp>
     <CatNumbers pofis-number="3"/>
     <Value kc-value="18" h-value="50"/>
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="4"/>
     <Value kc-value="14" />
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="5"/>
     <Value kc-value="0" l-value="A" />
     <Formats se-tenant="1"/>
</Stamp>
</Set>
~/t/ftemp $


--
Contact us for world-wide XML consulting and instructor-led training
Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/s/
G. Ken Holman                   mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Google+ profile: https://plus.google.com/116832879756988317389/about
Legal business disclaimers:    http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--