I have an XML file like this:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<letter n="1">
<p>test 1</p>
</letter>
<letter n="2">
<p>test 2</p>
</letter>
<letter n="3">
<p>test 3</p>
</letter>
<letter n="4">
<p>test 4</p>
</letter>
</xml>
My current stylesheet, which is not working as expected, looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" version="2.0">
<xsl:output name="xml" method="xml" indent="yes"/>
<!-- directory of new files -->
<xsl:param name="dir">/ex/ex/ex/test</xsl:param>
<!-- new file name = count existing xml files in directory and increment the value by 1 -->
<xsl:param name="filename"
select="count(collection('/ex/ex/ex/test?select=*.xml')) 1"/>
<!-- output xml file for each letter-tag -->
<xsl:template match="letter">
<xsl:for-each-group select="." group-by="./@n">
<xsl:for-each select="current-group()">
<xsl:result-document format="xml" href="{$dir}/{$filename}.xml">
<xsl:copy-of select="./node()"/>
</xsl:result-document>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
What I want to do: Read the XML file to be transformed, find all the letter tags and create a new XML file for each letter tag. (In this example the desired output would be 4 new XML files, the first with <p>test 1</p>
, the second with <p>test 2</p>
etc.) The file name should be the number of existing XML files in the output directory 1. So if I already have 10 files in my output directory, I want the new files to be named 11.xml, 12.xml etc. And this is what isn't working.
My problem is that I get the error message "cannot write more than one result document to the same URI".
What I want to know: How can I adapt my stylesheet to get my desired result, i. e. what can I do to output multiple XML files with an incremented parameter/variable as file name?
CodePudding user response:
If I read your requirements correctly, you want to do:
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:param name="dir">/ex/ex/ex/test</xsl:param>
<xsl:variable name="n" select="count(collection(concat($dir, '?select=*.xml')))"/>
<xsl:template match="/xml">
<xsl:for-each select="letter">
<xsl:result-document href="{$dir}/{$n position()}.xml">
<xsl:copy-of select="p"/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>