Subject: [xsl] XPath selecting chain of following siblings of the same name From: Kolací Tomáš <kolaci@xxxxxxx> Date: Fri, 9 Mar 2007 14:29:29 +0100 |
Hi! I have following input XML: <root> <a id="1"/> <a id="2"/> <b/> <d/> <g/> <a id="3"/> <a id="4"/> <a id="5"/> <x/> <a id="6"/> <a id="7"/> </root> and I'm trying to create XSLT 1.0 script, which would nest "uninterrupted" sibling groups of 'a' elements into 'a-block' elements, so the output would look like: <root> <a-block> <a id="1"/> <a id="2"/> </a-block> <b/> <d/> <g/> <a-block> <a id="3"/> <a id="4"/> <a id="5"/> </a-block> <x/> <a-block> <a id="6"/> <a id="7"/> </a-block> </root> How should look XPath selecting next 'a' elements of the same group in template matching first group element? I was able to create this (see second xsl:copy-of) (derived from http://www.biglist.com/lists/xsl-list/archives/200208/msg01182.html idea): <xsl:template match="a"> <xsl:if test="not(preceding-sibling::*[1][self::a])"> <!-- first node of each group --> <xsl:element name="a-block"> <xsl:copy-of select="."/> <xsl:copy-of select="following-sibling::a [preceding-sibling::*[1][self::a]] [generate-id(preceding-sibling::a[not(preceding-sibling::*[1][self: :a])][1]) = generate-id(current())]"/> <!-- first condition selects only 2nd+ nodes of each group --> <!-- second condition checks if the 1st node of the group is the current one --> </xsl:element> </xsl:if> </xsl:template> and it works (as far as I have test it up to now), but it's ugly, there must be something simpler..? Thanks in advance! Best regards, Tomas Kolaci ____________________ Full script (it does not handle white spaces correctly, but it does not matter in this case): <?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" indent="no"/> <xsl:template match="root"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="a"> <xsl:if test="not(preceding-sibling::*[1][self::a])"> <!-- first node of each group --> <xsl:element name="a-block"> <xsl:copy-of select="."/> <xsl:copy-of select="following-sibling::a [preceding-sibling::*[1][self::a]] [generate-id(preceding-sibling::a[not(preceding-sibling::*[1][self: :a])][1]) = generate-id(current())]"/> <!-- first condition selects only 2nd+ nodes of each group --> <!-- second condition checks if the 1st node of the group is the current one --> </xsl:element> </xsl:if> </xsl:template> <xsl:template match="*"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] xsl:number from="/" level, Deborah Pickett | Thread | Re: [xsl] XPath selecting chain of , Martin Honnen |
Re: [xsl] Schema-aware validation o, David Carlisle | Date | Re: [xsl] Schema-aware validation o, Jesper Tverskov |
Month |