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.
CodePudding user response:
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>