Split XML into multiple files using xslt on string length

460 Views Asked by At

I'm looking at trying to split an XML file into 2 separate files. They have to be split on the length of a string in a particular element.

I've been attempting to use the <xsl:for-each-group> and <xsl:result-document> elements in order to do this but only get the 1st matching 'object' in the result file.

For example:

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book>
        <bookId>4125151</bookId>
        <author>John Davies</author>
    </book>
    <book>
        <bookId>1000257896</bookId>
    <author>Lee Frost</author>
    </book>
    <book>
        <bookId>1234569870</bookId>
        <author>Joe Walters</author>
    </book>
    <book>
        <bookId>2145789</bookId>
        <author>Sarah Wyer</author>
    </book>
    <book>
        <bookId>4085151</bookId>
        <author>Jane Cohen</author>
    </book>
</books>

XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="books">
 <xsl:for-each-group select="book[string-length(bookId)!=10]" group-by="string-length(book/bookId)">

    <xsl:result-document href="file:/C:/devFiles/legacy.xml">
        <xsl:copy-of select="." />
    </xsl:result-document>

    </xsl:for-each-group>
 </xsl:template>

</xsl:stylesheet>

The result should be the books by John Davies, Joe Walters, Sarah Wyer and Jane Cohen all being saved in legacy.xml

Am I on the right track? Is there a better way?

Thanks in advance!

1

There are 1 best solutions below

1
On BEST ANSWER

I only need the 2 files. legacy.xml (bookIds not 10 in length) & current.xml (bookIds with length of 10).

Then I would suggest you do it this way:

XSLT 2.0

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

<xsl:template match="/books">
    <books>
        <xsl:copy-of select="book[string-length(bookId)=10]" />
    </books>
    <xsl:result-document href="file:/C:/devFiles/legacy.xml">
        <books>
            <xsl:copy-of select="book[string-length(bookId)!=10]" />
        </books>
  </xsl:result-document>
</xsl:template>

</xsl:stylesheet>

This will return the following:

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book>
        <bookId>1000257896</bookId>
      <author>Lee Frost</author>
    </book>
   <book>
        <bookId>1234569870</bookId>
        <author>Joe Walters</author>
    </book>
</books>

as the "normal" result of the transformation, which you can direct to a file when initiating the transformation, and also create the legacy.xml file containing:

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book>
        <bookId>4125151</bookId>
        <author>John Davies</author>
    </book>
   <book>
        <bookId>2145789</bookId>
        <author>Sarah Wyer</author>
    </book>
   <book>
        <bookId>4085151</bookId>
        <author>Jane Cohen</author>
    </book>
</books>