xsl-list
[Top] [All Lists]

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

2007-03-09 08:05:34
Kolací Tomáš 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
        

--~------------------------------------------------------------------
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>
--~--