[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Identifying unique attribute values in nested sibl

Subject: Re: Identifying unique attribute values in nested sibling elements
From: "Mark" <mark@xxxxxxxxxxxx>
Date: Wed, 5 Oct 2011 14:33:40 -0700
Re:  Identifying unique attribute values in nested sibl
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@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: 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@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 <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(.),'&#xfdd0;',.,'&#xfdd0;'"/>
    </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
<xsl:text/>
          </a>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
 </xsl:function>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.