Question

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

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top