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>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--