XSLT – Result documents merged into one messy file

I want to transform a larger XML file into smaller files AND store the data in another flavor of XML. XSLT seems like the obvious choice. But the script I wrote creates a messy output. Instead of separating the entries into distinct files, it creates files that contain all the data from all the entries.

This is the source file:

<RDF>
    <Manuscript>
        <authors>
            <Seq>
                <li>
                    <Person>
                       <surname>Meier</surname>
                        <givenName>Joseph</givenName>
                    </Person>
                </li>
            </Seq>
        </authors>
        <title>Poems</title>
        <language>German</language>
    </Manuscript>
    <Manuscript>
        <authors>
            <Seq>
                <li>
                    <Person>
                        <surname>Levinger</surname>
                        <givenName>Hans</givenName>
                    </Person>
                </li>
            </Seq>
        </authors>
        <title>The Arts Book</title>
        <language>English</language>
    </Manuscript>
    <Manuscript>
        <authors>
            <Seq>
                <li>
                    <Person>
                        <surname>Hills</surname>
                        <givenName>Samson</givenName>
                    </Person>
                </li>
            </Seq>
        </authors>
        <title>Creation</title>
        <language>English</language>
    </Manuscript>
</RDF>

This is my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >
    <xsl:output encoding="UTF-8" indent="yes" method="xml" name="xml"/>
    <xsl:template match="/">
        <xsl:for-each select="/RDF/Manuscript">
            <xsl:result-document
                method="xml" include-content-type="no"
                href="{concat(Manuscript, position(), '.xml')}" format="xml">
                                        <msItem>
                                            <title>
                                                <xsl:value-of select="//title"/>
                                            </title>
                                            <xsl:apply-templates select="//authors//Person"/>
                                            <textLang>
                                                <xsl:value-of select="//language"/>
                                            </textLang>
                                        </msItem>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="//authors//Person">
        <author>
            <persName>
                <xsl:apply-templates select="givenName"/>
                <xsl:text> </xsl:text>
                <xsl:apply-templates select="surname"/>
            </persName>
        </author>
    </xsl:template>
</xsl:stylesheet>

The result (1.xml, 2.xml, 3.xml):

<?xml version="1.0" encoding="UTF-8"?>
<msItem>
   <title>Poems The Arts Book Creation</title>
   <author>
      <persName>Joseph Meier</persName>
   </author>
   <author>
      <persName>Hans Levinger</persName>
   </author>
   <author>
      <persName>Samson Hills</persName>
   </author>
   <textLang>German English English</textLang>
</msItem>

The intended results:

1.xml

<?xml version="1.0" encoding="UTF-8"?>
<msItem>
   <title>Poems</title>
   <author>
      <persName>Joseph Meier</persName>
   </author>
   <textLang>German</textLang>
</msItem>

2.xml

<?xml version="1.0" encoding="UTF-8"?>
<msItem>
   <title>The Arts Book</title>
   <author>
      <persName>Hans Levinger</persName>
   </author>
   <textLang>English</textLang>
</msItem>

3.xml

<?xml version="1.0" encoding="UTF-8"?>
<msItem>
   <title>Creation</title>
   <author>
      <persName>Samson Hills</persName>
   </author>
   <textLang>English</textLang>
</msItem>

I have rebuilt the XSLT several times and I am no closer to figuring out where my mistake is.

>Solution :

Use relative paths inside of the for-each, starting with e.g. <xsl:result-document method="xml" include-content-type="no" href="{concat(title, position(), '.xml')}" format="xml"> and continuing with

<msItem>
                                        <title>
                                            <xsl:value-of select="title"/>
                                        </title>
                                        <xsl:apply-templates select="authors//Person"/>
                                        <textLang>
                                            <xsl:value-of select="language"/>
                                        </textLang>
                                    </msItem>

Leave a Reply