Subject: Re: [xsl] Finding the first among equals using XPath From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx> Date: Thu, 22 Jun 2006 12:02:27 -0400 |
I am sure this is a hoary old one, but I could not work out the right runes to achieve it, nor the right keywords to search for to find an answer
I a have a for-each loop over the W elements. Inside the for-each I want to select one X with each value of Y that exists within that W.
So for the above example, for //W[1] I want to get the first and third or second and third X elements, for //W[2] I want all three X elements and for //W[3] I want any one of the X elements, but only one of them.
I hope that bit is clear. .. I want a node-set so I can do a for-each on that, so I would prefer to find a select specifier based on clever use of axes and predicates.
Two answers are below ... both over a node set ... but the first is the variable-based method which allows one to do grouping directly over subtrees, but requires an <xsl:if> in the loop. The second is using the Muenchian method and gives a pure node set but the subtree distinction achieved through the use of the parent's generated identifier may make those responsible for maintaining it difficult to understand what is going on.
I am stuck with using XSL 1.0
t:\ftemp>type peter.xml <V> <W> <Z/> <X Y='0'/> <X Y='0'/> <X Y='1'/> <Z/> </W> <W> <Z/> <Z/> <X Y='0'/> <X Y='1'/> <X Y='2'/> </W> <W> <X Y='2'/> <X Y='2'/> <X Y='2'/> <Z/> <Z/> </W> </V>
t:\ftemp>type peter.xsl <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="V"> <xsl:for-each select="W"> <xsl:value-of select="concat('/V/W[',position(),']')"/> <xsl:text> </xsl:text> <xsl:variable name="Xs" select="X"/> <xsl:for-each select="$Xs"> <xsl:if test="generate-id(.)=generate-id($Xs[@Y=current()/@Y][1])"> <xsl:value-of select="concat('got X/@Y="',@Y,'"')"/> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> </xsl:template>
</xsl:stylesheet> t:\ftemp>xslt peter.xml peter.xsl con /V/W[1] got X/@Y="0" got X/@Y="1" /V/W[2] got X/@Y="0" got X/@Y="1" got X/@Y="2" /V/W[3] got X/@Y="2"
t:\ftemp>type peter2.xsl <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="V"> <xsl:for-each select="W"> <xsl:value-of select="concat('/V/W[',position(),']')"/> <xsl:text> </xsl:text> <xsl:variable name="Xs" select="X"/> <xsl:for-each select="$Xs[generate-id(.)= generate-id(key('Xs',concat(generate-id(..),' ',@Y))[1])]"> <xsl:value-of select="concat('got X/@Y="',@Y,'"')"/> <xsl:text> </xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template>
</xsl:stylesheet> t:\ftemp>xslt peter.xml peter2.xsl con /V/W[1] got X/@Y="0" got X/@Y="1" /V/W[2] got X/@Y="0" got X/@Y="1" got X/@Y="2" /V/W[3] got X/@Y="2"
-- Registration open for UBL training: Montrial, Canada 2006-08-07 Also for XSL-FO/XSLT training: Minneapolis, MN 2006-07-31/08-04 Also for UBL/XML/XSLT/XSL-FO training: Varo,Denmark 06-09-25/10-06 World-wide corporate, govt. & user group UBL, XSL, & XML training. G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995) Male Cancer Awareness Aug'05 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Finding the first among e, Peter Riocreux | Thread | Re: [xsl] Finding the first among e, Wendell Piez |
Re: [xsl] Finding the first among e, David Carlisle | Date | Re: [xsl] Finding the first among e, Wendell Piez |
Month |