Re: Counting siblings...
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 v18.104.22.168 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
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format