XSLT to tun flat xml structure into hierarchical

35 Views Asked by At

I need an xslt that can take a flat xml and turn it into a hierarchical structure. The source is like:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:FlatInfo xmlns:ns0="http://mynamespace.com">
    <Header>
        <OrderNo>100</OrderNo>
    </Header>
    <Item>
        <ItemNo>1</ItemNo>
        <Product>Slime</Product>
        <Quantity>2</Quantity>
    </Item>
    <Item>
        <ItemNo>2</ItemNo>
        <Product>Gunge</Product>
        <Quantity>4</Quantity>
    </Item>
    <Header>
        <OrderNo>102</OrderNo>
    </Header>
    <Item>
        <ItemNo>1</ItemNo>
        <Product>Sludge</Product>
        <Quantity>55</Quantity>
    </Item>
</ns0:FlatInfo>

This needs to become:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:TreeInfo xmlns:ns0="http://mynamespace.com">
    <Header>
        <OrderNo>100</OrderNo>
        <Item>
            <ItemNo>1</ItemNo>
            <Product>Slime</Product>
            <Quantity>2</Quantity>
        </Item>
        <Item>
            <ItemNo>2</ItemNo>
            <Product>Gunge</Product>
            <Quantity>4</Quantity>
        </Item>
    </Header>
    <Header>
        <OrderNo>102</OrderNo>
        <Item>
            <ItemNo>1</ItemNo>
            <Product>Sludge</Product>
            <Quantity>55</Quantity>
        </Item>
    </Header>
</ns0:TreeInfo>

The only thing that links the items to the headers is the order in that they are output in the source xml. Please can someone suggest the best way to achieve this.

New to xslt and struggling to get this working

1

There are 1 best solutions below

0
Michael Kay On

It's essentially

<xsl:template match="*:FlatInfo">
  <xsl:for-each-group select="*" group-starting-with="Header">
    <Header>
      <xsl:copy-of select="current-group()/(*/OrderNo, Item)"/>
    </Header>
  </xsl:for-each-group>
</xsl:template>