Hi Brandon,
First, I am saying absolutely nothing negative here about Ken's version --
he has been generous and most helpful for a considerable time now. Thanks,
Ken.
That said, what strikes me about your implementation is that you have
structured it in an idiom I find quite familiar. What I see in your code are
polymorphic functions calling upon the data rather than the code to do the
messaging. Had I a far better command of XPath and were I more sensitive to
power of XSLT, I suspect I might produce something similar your
implementation. I find its polymorphic task resolution extremely satisfying.
I think you are aware that my native coding language is C++. So far, I have
been unsuccessful in leveraging my hard-earned C++ skill set to advantage
with respect to XSLT and XPath. Your essay has given me a leg up.
Thanks,
Mark
-----Original Message-----
From: Brandon Ibach
Sent: Wednesday, October 05, 2011 1:15 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Identifying unique attribute values in nested sibling
elements
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(_at_)knihtisk(_dot_)org> wrote:
Hi Ken,
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>Kč</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="."/>Kč<xsl:text/>
</a>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:function>
--~------------------------------------------------------------------
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>
--~--
--~------------------------------------------------------------------
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>
--~--