Splitting XML into multiple files with XSLT

Solution 1:

Responding to your comment on @Dimitre's answer...

You wrote,

<xsl:template match="/">
  <xsl:for-each select="elem/file">
    <xsl:result-document method="xml" href="file_{@id}-output.xml">
      <xsl:copy-of select="."/>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template> 

This doesn't quite match your XML, which has rootelem as an outermost element, and your comment says root as an outermost element. You probably want something like this:

<xsl:template match="/root">
  <xsl:for-each select="elem/file">
    <xsl:result-document method="xml" href="file_{@id}-output.xml">
      <root>
        <xsl:copy-of select="/root/@*" />
        <elem>
          <xsl:copy-of select="../@* | ." />
        </elem>
      </root>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template> 

You could get fancier, trying to use <xsl:copy> instead of literal result elements for root and elem, but it doesn't seem worth the effort unless they're going to vary.

Solution 2:

It is not possible in pure XSLT 1.0 to produce more than one output files. One could use the <exslt:document> extension element for this purpose.

In XSLT 2.0 use the <xsl:result-document> element.

Solution 3:

If you want to use

<xsl:result-document method="xml" href="file_{@id}-output.xml">

from an ANT xslt call, you need to use 2.0., just add the following in your ANT call:

<classpath location="/home/ap/saxon/saxon8.jar" />

And specifiy Version="2.0" And enjoy file splitting.