Subject: Re: Counting siblings... From: Nick Browne <NickBrowne@xxxxxxxxxxxxxxx> Date: Fri, 16 Jun 2000 12:47:09 +0100 |
Here is a solution to your problem of counting siblings up to a certain point. I have put a slightly enhanced version of your XML document at the end. I hope my use of the word 'context' in the comments is correct ! The Style sheet : <?xml version="1.0" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template match="root"> <xsl:for-each select="item"> Item : <xsl:value-of select="position()"/> has : <xsl:call-template name="levelchk"> <xsl:with-param name="lvl" select="@level"/> <xsl:with-param name="cnt" select="number(0)"/> <xsl:with-param name="pos" select="position()"/> </xsl:call-template> </xsl:for-each> </xsl:template> <!-- Using the (single) item initially passed from the for-each as the context, work forward via recursion until an item is found that has the same or lower level attribute value --> <xsl:template name="levelchk"> <xsl:param name="lvl"/> <xsl:param name="cnt"/> <xsl:param name="pos"/> <!-- Decide whether we need to keep searching .. --> <xsl:choose> <!-- If there is still another following item with a level attribute value higher than the context value, call the template again and repeat the check for the next item --> <xsl:when test="../item[$pos+1]/@level > $lvl"> <xsl:call-template name="levelchk"> <xsl:with-param name="lvl" select="$lvl"/> <xsl:with-param name="cnt" select="$cnt+1"/> <xsl:with-param name="pos" select="$pos+1"/> </xsl:call-template> </xsl:when> <!-- Stop the search. If here then we have found an item where the level attribute value is less than the level value from the context item (or $pos points to the last item) --> <xsl:otherwise> <xsl:value-of select="$cnt"/> 'descendants' <BR /> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> Notes : 1. The variable $lvl is not necessary. 'param' references to it can be removed and the 'when' test can refer to @level (since there is only one item in the templates context) 2. Tested on Oracle v2.0.2.8 The XML document : (the text of item is the items position in the document followed by the result you were after, i.e. for each item, how many siblings does it have which have a level attribute value that is greater than that of the item itself, stop counting once the first sibling is found with a level value less than or equal to that of the item itself.) : <?xml version="1.0" encoding="ISO-8859-1" ?> <root> <item level="0">1-4</item> <item level="1">2-1</item> <item level="2">3-0</item> <item level="1">4-1</item> <item level="2">5-0</item> <item level="0">6-3</item> <item level="1">7-2</item> <item level="2">8-1</item> <item level="3">9-0</item> </root> I had tried to use the 'Muenchian' technique but your data does not have a natural key. May be someone else would know if this is a better approach ? Hope this helps. Nick Browne Slipstone Ltd Giles Smith wrote: > Hi, > > I have an interesting problem, and wondered if your clever people might be > able to offer some possible solutions: etc. XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Counting siblings..., Giles Smith | Thread | XML + XSL on internet navigators, Stéphane Mamdy |
break-before="page", SoftLiban DACCACHE W | Date | RenderX: HTML to PDF via XSL FO For, David Tolpin |
Month |