Subject: Re: [xsl] Identifying unique attribute values in nested sibling elements From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx> Date: Wed, 5 Oct 2011 16:15:47 -0400 |
To go a bit beyond Ken's suggestions, here's a very non-C++ style of approach, relying on the data to drive the processing, which XSLT supports very well. This assumes that you only have a single Value element in each Stamp. Your code seemed to indicate that this was the case and your use of <xsl:for-each> seemed to be mostly for purposes of shifting your context, but if there's a chance you might have more than one Value, that would make for some strange results, so it's something to look out for, if you don't have a schema to enforce such rules on your input. Hopefully, this isn't too hard to follow. I have a weakness for C-cubed code (concise, clever and, all too often, a bit cryptic). Besides the more content-driven style, the other main feature here is the simplification allowed by the fact that in all cases, your code was generating an <a class="button">, so you may as well only generate it once (the "DRY" rule works in any sort of programming, after all, regardless of the language used). <xsl:function name="cps:report"> <xsl:param name="Stamp"/> <xsl:variable name="file"> <xsl:apply-templates select="$Stamp/Value" mode="cps:href"/> </xsl:variable> <a class="button" href="../aval/{$file}.htm"> <xsl:apply-templates select="$Stamp/Value" mode="cps:text"/> </a> </xsl:function> <xsl:template match="Value[@l-value]" mode="cps:href"> <xsl:value-of select="lower-case(@l-value)"/> </xsl:template> <xsl:template match="Value[not(@l-value)]" mode="cps:href"> <xsl:value-of select="concat((@kc-value, 0)[1], '-')"/> <xsl:value-of select="(@h-value, 0)[1]"/> </xsl:template> <xsl:template match="Value[@l-value]" mode="cps:text"> <xsl:value-of select="@l-value"/> </xsl:template> <xsl:template match="Value[not(@l-value)]" mode="cps:text"> <xsl:variable name="kc" select="@kc-value[. ne '0']"/> <xsl:variable name="h" select="@h-value[. ne '0']"/> <xsl:value-of select="concat($kc, '.'[$kc][$h], $h)"/> <xsl:value-of select="if ($kc) then 'Kc' else 'h'"/> </xsl:template> -Brandon :) On Tue, Oct 4, 2011 at 10:23 AM, Mark <mark@xxxxxxxxxxxx> wrote: > Hi Ken, > Despite my confused presentation of the problem last week, you supplied me > with two functions that obtain the unique attributes from B <Value> element > within a set of <Stamp> elements. Works beautifully, but I did make some > modifications to the second function. Please let me know if my modifications > are consistent with the idiom you have been talking about or if I have > slipped back into C++. Any improvements would be greatly appreciated if and > when you have the time and desire. The h-value and l-value were not > presented to you as part of the original use case. > > They do exactly what I wanted. > Thanks, > Mark > > the XML with the B output: > <Value kc-value="1"> B B B B B B B B B B B B Text: 1kc B B File: 1-0.htm > <Value kc-value="1" h-value="50"> Text 1.50kc File: 1-50.htm > <Value kc-value="0" h-value="50"> Text: 50h B File: 0-50.htm > <Value kc-value="0" l-value="A" B B Text: A B File:a.htm > > Only the second function, cps:report, has been modified: > > <!--compose a string of attribute names and their values; > B avoid the possibility of co-incidental string values;--> > B <xsl:function name="cps:attrs"> > B <xsl:param name="this"/> > B <xsl:value-of> > B B <xsl:for-each select="$this/@*"> > B B B <xsl:sort select="name(.)"/> > B B B <xsl:value-of select="name(.),'',.,''"/> > B B </xsl:for-each> > B </xsl:value-of> > B </xsl:function> > > B <!--common reporting--> > B <xsl:function name="cps:report"> > B <xsl:param name="Stamp"/> > B <xsl:for-each select="$Stamp"> > B B <!-- l-value --> > B B <xsl:choose> > B B B <xsl:when test="Value/@l-value"> > B B B B <xsl:for-each select="Value/@l-value"> > B B B B B <a class="button" href="../aval/{lower-case(.)}.htm"> > B B B B B B <xsl:value-of select="."/> > B B B B B </a> > B B B B </xsl:for-each> > B B B </xsl:when> > B B B <!-- kc-value + h-value --> > B B B <xsl:when test="Value/@h-value"> > B B B B <xsl:variable name="h"> > B B B B B <xsl:for-each select="Value/@h-value"> > B B B B B B <xsl:value-of select="."/> > B B B B B </xsl:for-each> > B B B B </xsl:variable> > B B B B <xsl:for-each select="Value/@kc-value"> > B B B B B <xsl:choose> > B B B B B B <xsl:when test="not(. eq '0')"> > B B B B B B B <a class="button" href="../aval/{concat(., '-', $h)}.htm"> > B B B B B B B B <xsl:value-of select="concat(., '.', $h)"/> > B B B B B B B B <xsl:text>KD </xsl:text> > B B B B B B B </a> > B B B B B B </xsl:when> > B B B B B B <xsl:otherwise> > B B B B B B B <a class="button" href="../aval/{concat(., '-', $h)}.htm"> > B B B B B B B B <xsl:value-of select="$h"/> > B B B B B B B B <xsl:text>h</xsl:text> > B B B B B B B </a> > B B B B B B </xsl:otherwise> > B B B B B </xsl:choose> > B B B B </xsl:for-each> > B B B </xsl:when> > > B B B <xsl:otherwise> > B B B B <!-- Only when there is no h-value B --> > B B B B <xsl:for-each select="Value/@kc-value"> > B B B B B <a class="button" href="../aval/{concat(., '-0')}.htm"> > B B B B B B <xsl:value-of select="."/>KD <xsl:text/> > B B B B B </a> > B B B B </xsl:for-each> > B B B </xsl:otherwise> > B B </xsl:choose> > B </xsl:for-each> > B </xsl:function>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Identifying unique attrib, Mark | Thread | Re: [xsl] Identifying unique attrib, Mark |
[xsl] change xslt processing order, Navin Patel | Date | Re: [xsl] Identifying unique attrib, Mark |
Month |