[Home] [By Thread] [By Date] [Recent Entries]
Hi Everyone,
With an input XML of: <xml>
<a>
<b>
<node id="1"/>
<node id="2"/>
<node id="3"/>
<c>
<node id="4"/>
<node id="5"/>
<node id="6"/>
<d>
<node id="7"/>
<node id="8"/>
<node id="9"/>
</d>
<e>
<node id="10"/>
<node id="11"/>
<node id="12" current="true"/>
</e>
</c>
</b>
<b>
<node id="13"/>
</b>
<b>
<node id="14"/>
</b>
<b>
<node id="15"/>
</b>
</a>
</xml>I'm trying to identify those node elements immediately preceding and following the one marked current="true", but ONLY if within the same <b> element. For example, if node 6 is marked current, 5 and 7 will be preceding and following, respectively. If node 12 is current (as shown), 11 will be preceding, and since there are no more node elements within that <b>, there will be no following. Note that the depth of any given node element may be considered arbitrary within the heirarchy; the exact structure will not be known. I also need to output something if there is no "preceding" or "following" node. There will be only one node with the current="true" attribute. I have come up with 2 approaches so far (following only shown as the same approach can be used with preceding as well): <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="ascii" omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:variable name="current-node" select="//node[@current]"/> <xsl:template match="/"> current: <xsl:value-of select="$current-node/@id"/><br/> <xsl:choose> <xsl:when test="$current-node/following::node[1]/ancestor-or-self::b//node[@current]"> following: <xsl:value-of select="$current-node/following::node[1]/@id"/><br/> </xsl:when> <xsl:otherwise> no more<br/> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="generate-id($current-node/ancestor-or-self::b) = generate-id($current-node/following::node[1]/ancestor-or-self::b)"> following: <xsl:value-of select="$current-node/following::node[1]/@id"/><br/> </xsl:when> <xsl:otherwise> no more<br/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> The first approach tests whether the "following" node's <b> ancestor contains a node with the current="true" attribute. The second approach tests if the <b> elements which are ancestors of the current and following nodes are identical via the generate-id() function. Can anyone comment on the relative merits / problems of either approach? The first approach uses the frowned-upon //. Can anyone see a way to use a clever predicate instead of the ancestor-or-self axis? Is there an obvious solution that I'm missing? Many thanks for your time, Mike _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp. XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|

Cart



