|
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 |