Navin Dalal
Navin Dalal

Reputation: 179

Splitting of xml using xslt 2.0

        <r>
            <info> </info>
            <level id="some unique id" leveltype="group">
                <heading>
                    <title/>
                </heading>
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>
                <level id="some unique id 1" leveltype="para0">
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>
                </level>
    <level id="some unique id 2" leveltype="para0">
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>
                </level>
            </level>
        </r>

this structure repeat itself with level of leveltype group contains many para0 so i have a task to split file on basis of para0 leveltype .

    below is my xslt code

        <xsl:stylesheet version="2.0" >
            <xsl:template match="/">
                <xsl:variable name="filename" select="replace(base-uri(),'.xml','')"/>
                <xsl:for-each select="//level[@leveltype='para0']">
                    <xsl:result-document method="xml" href="{$filename}{@id}.xml">
                        <xsl:copy-of select="//docinfo" copy-namespaces="no"></xsl:copy-of>
                        <xsl:element name="comm:body">
                            <xsl:choose>
                                <xsl:when test="./preceding-sibling::node()[@leveltype]='para0'">
                                 <xsl:copy-of select="."></xsl:copy-of>   
                                </xsl:when>
                                <xsl:otherwise><xsl:copy-of select="./parent::node()"></xsl:copy-of>                 
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:element>
                    </xsl:result-document>
                </xsl:for-each>

            </xsl:template>    
        </xsl:stylesheet>

Problem i am facing is i am getting the both para0 in splitted files if a group contain 2 par0 leveltype

    output:-

    some unique id 1.xml

    <r>
            <info> </info>
            <level id="some unique id" leveltype="group">
                <heading>
                    <title/>
                </heading>
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>
                <level id="some unique id 1" leveltype="para0">
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>
                </level>
    </level>
    </r>



 # some unique id 2.xml(split at 2nd para0 and group should not be present in this file )



    <r>
                <info> </info>
<level id="some unique id" leveltype="group">
                    <heading>
                        <title/>
                    </heading>
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>                    
<level id="some unique id 2" leveltype="para0">
                        <bodytext>
                            <p>
                                <text>some text with tags and attribute</text>
                            </p>
                        </bodytext>
                    </level>
</level
        </r>



#  For second nested para0 group should not be there in the output file

Upvotes: 0

Views: 237

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

Assuming each splitted file is supposed to contain everything but the different leveltype para0 elements I would use an approach like

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <xsl:apply-templates select="//level[@leveltype = 'para0']" mode="file"/>
</xsl:template>

<xsl:template match="level[@leveltype = 'para0']" mode="file">
  <xsl:result-document href="output{@id}.xml">
    <xsl:apply-templates select="/*">
      <xsl:with-param name="copy" tunnel="yes" select="current()"/>
    </xsl:apply-templates>
  </xsl:result-document>
</xsl:template>

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

<xsl:template match="level[@leveltype = 'para0']">
  <xsl:param name="copy" tunnel="yes"/>
  <xsl:if test=". is $copy">
    <xsl:next-match/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

For the sample input

    <r>
        <info> </info>
        <level id="some unique id" leveltype="group">
            <heading>
                <title/>
            </heading>
            <bodytext>
                <p>
                    <text>some text with tags and attribute</text>
                </p>
            </bodytext>
            <level id="l01" leveltype="para0">
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>
            </level>
<level id="l02" leveltype="para0">
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>
            </level>
        </level>
    </r>

I get two files

<?xml version="1.0" encoding="UTF-8"?><r>
            <info> </info>
            <level id="some unique id" leveltype="group">
                <heading>
                    <title/>
                </heading>
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>
                <level id="l01" leveltype="para0">
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>
                </level>

            </level>
        </r>

and

<?xml version="1.0" encoding="UTF-8"?><r>
            <info> </info>
            <level id="some unique id" leveltype="group">
                <heading>
                    <title/>
                </heading>
                <bodytext>
                    <p>
                        <text>some text with tags and attribute</text>
                    </p>
                </bodytext>

    <level id="l02" leveltype="para0">
                    <bodytext>
                        <p>
                            <text>some text with tags and attribute</text>
                        </p>
                    </bodytext>
                </level>
            </level>
        </r>

Upvotes: 0

Related Questions