Subject: [xsl] numbering nodes (by context | input), but not single ones From: "Fries, Markus, fiscus GmbH, Bonn" <M.Fries@xxxxxxxxxxx> Date: Fri, 12 Apr 2002 19:27:34 +0200 |
Hi, The files are only that long, because there are lots of comments. :) I want to number the subitems. If they occur alone, no number should be displayed, otherwise the numbers should be 1, 2, ... like this <item> <subitem>no number here</subitem> </item> <item> <subitem> numbering should occur</subitem> <subitem> numbering should occur</subitem> <subitem> numbering should occur</subitem> <subitem> numbering should occur</subitem> </item> Ok. Thats fine, with the templates I wrote. 1. But I can not exclude those subitems with attributes. <subitem typ="foo">not here</subitem> See bottom of testNumber.xsl : 2. Does this cost a lot, and if yes is there a cheaper method? <xsl:if test="preceding-sibling::* or following-sibling::*"> <xsl:value-of select="concat(' ', count(preceding-sibling::*) + 1)"/> </xsl:if> I guess xslt 2.0 would save me from all that hazzle... Unfortunately I am restricted to xalan. Regards Markus Fries -- number.xsl <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/> <!-- This stylesheet provides two modes for numbering --> <!-- mode="numberByContext" Numbers the current nodeset according to context. As numbering is according to context, sorting is possible. Single nodes are not numbered. --> <!-- Be aware to put only the right nodes into context. If comments, textnodes (especially whitespace) are included, they will be counted and gaps in the numbers output appear. Included elements with no output, will result in output of their number. A "robust" behaviour would cost perfomance. Usage: When you need to select a part of the source tree. When it is not necessary to do anything else than performing the templates on the respective nodes and appending the number. --> <!-- "last() = 1" i.e. the only element in the context. no number will be appended. --> <xsl:template match="*[last() = 1]" mode="numberByContext"> <xsl:apply-templates select="."/> </xsl:template> <!-- "last() != 1" i.e the are more elements in the context. the respective number will be appended.--> <xsl:template match="*[last() != 1]" mode="numberByContext"> <xsl:apply-templates select="."/><xsl:value-of select="concat(' ', position())"/> </xsl:template> <!-- mode="numberedByInput" Numbers current node according to the position in the source tree. Single nodes are not numbered. --> <!-- Comments and textnodes that are siblings are ignored. All elements on the sibling axis are counted, so an empty tag will result in numbers increased by 1 for following elements. <item> <noRefundPossible/> <subitem>eins</subitem> </item> <subitem>eins</subitem> is the second child and thus numbered with 2. Usage: Applicable when the numbers can be drawn from the source tree only. This restriction forbids sorting, and filters on the siblings. But it does allow to call the template with single nodes. Thus for-each loops can be used which add other stuff around the result. --> <xsl:template match="*" mode="numberByInput"> <xsl:apply-templates select="."/> <xsl:if test="preceding-sibling::* or following-sibling::*"> <xsl:value-of select="concat(' ', count(preceding-sibling::*) + 1)"/> </xsl:if> </xsl:template> <!-- The template which should just return the number --> <xsl:template match="*" mode="getPositionInput"> <xsl:if test="preceding-sibling::* or following-sibling::*"> <xsl:value-of select="concat(' ', count(preceding-sibling::*) + 1)"/> </xsl:if> </xsl:template> <!-- The template which should just return the number --> <xsl:template match="*" mode="getPositionContext"> <xsl:if test="last()!=1"><xsl:value-of select="concat(' ', position())"/></xsl:if> </xsl:template> </xsl:stylesheet> ---------------------------------------------------------------------------- ------------ -- testNumber.xsl <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml"/> <xsl:include href="number.xsl"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"> </xsl:template> <xsl:template match="text()" mode="numbered"> </xsl:template> <xsl:template match="subitem"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="item"> <!-- All that is commented out: <xsl:text>numbered, sorted: correct selection
</xsl:text> <xsl:apply-templates select="subitem" mode="numbered"> <xsl:sort/> </xsl:apply-templates> <xsl:text>
</xsl:text> <xsl:text>numbered, unsorted: no selection, thus wrong numbers
</xsl:text> <xsl:apply-templates mode="numbered"/> <xsl:text>
</xsl:text> <xsl:text>incorrect usage of numbered: only one node in context when used with for-each
</xsl:text> <xsl:for-each select="subitem"> <xsl:apply-templates select="." mode="numbered"/> <xsl:text>
</xsl:text> </xsl:for-each> <xsl:text>usage of numberedComplex: correct, if input contains no other elements.
</xsl:text> <xsl:for-each select="subitem"> <xsl:apply-templates select="." mode="numberedComplex"/> <xsl:text>
</xsl:text> </xsl:for-each> <xsl:text>
</xsl:text> --> <!-- ============================================================================ ========== --> <!-- Why does @typ!='foo' not work? They should not increment the counter --> <!-- getPosition... must of course only return the number for the last node. That should be easy. --> <!-- ============================================================================ ========== --> <xsl:for-each select="subitem"> <xsl:value-of select="."/> <xsl:apply-templates select="preceding-sibling::*[@typ!='foo']| ." mode="getPositionContext"/> <xsl:text>
</xsl:text> </xsl:for-each> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> ---------------------------------------------------------------------------- ------------------------------- -- testNumber.xml <testNumber> <item> <subitem>aOne</subitem> text <subitem typ="foo">dTwo</subitem> <noItem/> <subitem>cThree</subitem> <!-- comment --> <subitem>bFour</subitem> </item> <item> text <subitem>noNumber as single node</subitem> </item> </testNumber> Markus Fries fiscus GmbH +49 228 28 07-273 markus.fries@xxxxxxxxxxx XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] DOMSource into stylesheet, irene_hall | Thread | Re: [xsl] numbering nodes (by conte, Jeni Tennison |
Re: [xsl] XSL month sorting (chrono, murli bk | Date | Re: [xsl] numbering nodes (by conte, Jeni Tennison |
Month |