Ice2burn
Ice2burn

Reputation: 691

Splitting XML into multiple files using XSLT 2.0

Using XSLT 2.0 I try to split xml and separate all item groups.

Original xml:

<Root Name="Root1">
  <Info Name="Info1" />
  <Group id="1">
    <Client Code="1">
      <ItemGroup Name="Group1"><Data/></ItemGroup>
      <ItemGroup Name="Group2"><Data/></ItemGroup>
    </Client>
    <Client Code="2">
      <ItemGroup Name="Group3"><Data/></ItemGroup>
      <ItemGroup Name="Group4"><Data/></ItemGroup>
    </Client>
  </Group>
</Root>

Desired output, part1:

<Root Name="Root1">
  <Info Name="Info1" />
  <Group id="1">
    <Client Code="1">
      <ItemGroup Name="Group1"><Data/></ItemGroup>
    </Client>
  </Group>
</Root>

Desired output, part2:

<Root Name="Root1">
  <Info Name="Info1" />
  <Group id="1">
    <Client Code="1">
      <ItemGroup Name="Group2"><Data/></ItemGroup>
    </Client>
  </Group>
</Root>
enter code here

Desired output, part3:

<Root Name="Root1">
  <Info Name="Info1" />
  <Group id="1">
    <Client Code="2">
      <ItemGroup Name="Group3"><Data/></ItemGroup>
    </Client>
  </Group>
</Root>

Desired output, part4:

<Root Name="Root1">
  <Info Name="Info1" />
  <Group id="1">
    <Client Code="2">
      <ItemGroup Name="Group4"><Data/></ItemGroup>
    </Client>
  </Group>
</Root>

I managed to split it, but having difficulties to add the parent nodes.

My best attempt:

<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:template match="/Root/Group/Client">
      <xsl:for-each-group select="ItemGroup" group-by="@Name">
        <xsl:result-document href="ItemGroup_{current-grouping-key()}.xml">
            <xsl:copy-of select="current-group()"/>
        </xsl:result-document>
      </xsl:for-each-group>
    </xsl:template> 
</xsl:stylesheet>

Can you point me in the right direction?

Upvotes: 0

Views: 173

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

I think you want something like

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  
  <xsl:template match="/">
    <xsl:for-each-group select="Root/Group/Client/ItemGroup" group-by="@Name">
      <xsl:result-document href="ItemGroup_{current-grouping-key()}.xml">
          <xsl:apply-templates select="/*"/>
      </xsl:result-document>
    </xsl:for-each-group>
  </xsl:template>
  
  <xsl:mode on-no-match="shallow-copy"/>
  
  <xsl:template match="Group | Client | ItemGroup">
    <xsl:if test=". intersect current-group()/ancestor-or-self::*">
      <xsl:next-match/>
    </xsl:if>
  </xsl:template>
    
</xsl:stylesheet>

Online example.

Upvotes: 1

Related Questions