Re: [xsl] Need to Split/Un-Nest elements

Subject: Re: [xsl] Need to Split/Un-Nest elements
From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx>
Date: Thu, 12 Jun 2008 10:26:04 +0100
2008/6/12 Mandar Jagtap <mandar.jagtap@xxxxxxxxx>:
> Hi,
>
> I want to split/un-nest the elements in xml like below:
>
> Input xml:
>
>         <region>
>            <page>
>               <block>Text1.....</block>
>               <block>
>                    <inline>Text2.....</inline>
>                    <page>
>                        <block>Text3.....</block>
>                    </page>
>                    <inline>Text4......</inline>
>               </block>
>            </page>
>            <page>
>               <block>Text5.....</block>
>            </page>
>         </region>
>
> Desired Output:
>
>   <region>
>        <page>
>               <block>Text1.....</block>
>               <block>
>                     <inline>Text2.....</inline>
>               </block>
>        </page>
>        <page>
>               <block>Text3.....</block>
>        </page>
>        <page>
>               <block>
>                   <inline>Text4......</inline>
>               </block>
>        </page>
>        <page>
>               <block>Text5.....</block>
>        </page>
>
>   </region>
>
> Can anyone help me on this?


You need the "modified identity" or "sibling recursion" technique to
allow you stop processing as you come across a <page> element:


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

    <xsl:output indent="yes"/>

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

    <xsl:template match="@*">
        <xsl:copy/>
    </xsl:template>

    <xsl:template match="/region">
        <xsl:copy>
            <xsl:apply-templates
select="//page|//*[preceding-sibling::*[1][self::page]]" mode="copy"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="page" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]"/>
        </xsl:copy>	
    </xsl:template>

    <xsl:template match="inline" mode="copy">
        <page>
            <block>
                <xsl:apply-templates select="."/>
            </block>
        </page>	
    </xsl:template>

    <xsl:template match="page"/>

</xsl:stylesheet>


Sorry I don't have time to explain it...


-- 
Andrew Welch
http://andrewjwelch.com
Kernow: http://kernowforsaxon.sf.net/

Current Thread