Subject: Re: [xsl] Identifying unique attribute values in nested sibling elements From: "Mark" <mark@xxxxxxxxxxxx> Date: Wed, 5 Oct 2011 14:33:40 -0700 |
Thanks, Mark
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>
Hi Ken,</xsl:text>
Despite my confused presentation of the problem last week, you supplied me
with two functions that obtain the unique attributes from <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 output: <Value kc-value="1"> Text: 1kc 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 File: 0-50.htm <Value kc-value="0" l-value="A" Text: A File:a.htm
Only the second function, cps:report, has been modified:
<!--compose a string of attribute names and their values; avoid the possibility of co-incidental string values;--> <xsl:function name="cps:attrs"> <xsl:param name="this"/> <xsl:value-of> <xsl:for-each select="$this/@*"> <xsl:sort select="name(.)"/> <xsl:value-of select="name(.),'',.,''"/> </xsl:for-each> </xsl:value-of> </xsl:function>
<!--common reporting--> <xsl:function name="cps:report"> <xsl:param name="Stamp"/> <xsl:for-each select="$Stamp"> <!-- l-value --> <xsl:choose> <xsl:when test="Value/@l-value"> <xsl:for-each select="Value/@l-value"> <a class="button" href="../aval/{lower-case(.)}.htm"> <xsl:value-of select="."/> </a> </xsl:for-each> </xsl:when> <!-- kc-value + h-value --> <xsl:when test="Value/@h-value"> <xsl:variable name="h"> <xsl:for-each select="Value/@h-value"> <xsl:value-of select="."/> </xsl:for-each> </xsl:variable> <xsl:for-each select="Value/@kc-value"> <xsl:choose> <xsl:when test="not(. eq '0')"> <a class="button" href="../aval/{concat(., '-', $h)}.htm"> <xsl:value-of select="concat(., '.', $h)"/> <xsl:text>KD
<xsl:text/></a> </xsl:when> <xsl:otherwise> <a class="button" href="../aval/{concat(., '-', $h)}.htm"> <xsl:value-of select="$h"/> <xsl:text>h</xsl:text> </a> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:when>
<xsl:otherwise> <!-- Only when there is no h-value --> <xsl:for-each select="Value/@kc-value"> <a class="button" href="../aval/{concat(., '-0')}.htm"> <xsl:value-of select="."/>KD
</a> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:function>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Identifying unique attrib, Brandon Ibach | Thread | [xsl] max string-length for context, Eric Harbeson |
Re: [xsl] Identifying unique attrib, Brandon Ibach | Date | Re: [xsl] how to trigger a new page, team wise |
Month |