Re: [xsl] XPath selecting chain of following siblings of the same name

Subject: Re: [xsl] XPath selecting chain of following siblings of the same name
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Fri, 09 Mar 2007 16:05:10 +0100
Kolacm Toma9 wrote:

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

I think this stylesheet does what you want:


<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="1.0">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="a-group" match="a" use="generate-id(preceding-sibling::*[not(self::a)][1])"/>

<xsl:template match="root">
  <xsl:copy>
    <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="a[preceding-sibling::*[1][not(self::a)] or not(preceding-sibling::*)]">
<a-block>
<xsl:apply-templates select="key('a-group', generate-id(preceding-sibling::*[not(self::a)][1]))" mode="copy"/>
</a-block>
</xsl:template>


<xsl:template match="a[preceding-sibling::*[1][self::a]]"/>

<xsl:template match="a" mode="copy">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="* | @*">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>


--


Martin Honnen

Current Thread