Reputation: 15816
I have a long list of values in XML with named identifiers. I need to make separate output files for each of the distinct identifiers grouped together and uniquely named.
So, for example, let's say I have:
<List>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
Hello World!
</Item>
<Item group="::this_other_long_and_complicated_group_name_that_cannot_be_a_filename::">
Goodbye World!
</Item>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
This example text should be in the first file
</Item>
<Item group="::this_other_long_and_complicated_group_name_that_cannot_be_a_filename::">
This example text should be in the second file
</Item>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
Hello World!
</Item>
</List>
How can I write a transformation (XSLT 2.0) to output these grouped into generated filenames and uniquely valued? For example: mapping the first @group
to file1.xml and the second @group
to file2.xml
Upvotes: 4
Views: 594
Reputation: 243529
Here is a solution that uses some of the good new features in XSLT 2.0:
This transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<!-- -->
<xsl:template match="/*">
<xsl:variable name="vTop" select="."/>
<!-- -->
<xsl:for-each-group select="Item" group-by="@group">
<xsl:result-document href="file:///C:/Temp/file{position()}.xml">
<xsl:element name="{name($vTop)}">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
when applied on the OP-provided Xml document (corrected to be well-formed!):
<List>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
Hello World!
</Item>
<Item group="::this_other_long_and_complicated_group_name_that_cannot_be_a_filename::">
Goodbye World!
</Item>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
This example text should be in the first file
</Item>
<Item group="::this_other_long_and_complicated_group_name_that_cannot_be_a_filename::">
This example text should be in the second file
</Item>
<Item group="::this_long_and_complicated_group_name_that_cannot_be_a_filename::">
Hello World!
</Item>
</List>
produces the wanted two files: file1.xml and file2.xml
Upvotes: 3