M4rk0444
M4rk0444

Reputation: 73

How to transform Xml to hierarchical Xml

I have this XML file and want to perform an Xslt 2.0 Transformation.

The Problem is, that the the nodes are at the same Level and reference to each other with ID's, for example:

<?xml version="1.0" encoding="UTF-8"?>

<Data id = "1" referenceID = "2 3">
    Text1
</Data>

<Data id = "2" referenceID = "4">
    Text2
</Data>

<Data id = "3" referenceID = "5">
    Text3
</Data>

<Data id = "4">
    Text4
</Data>

<Data id = "5">
    Text5
</Data>

The desired Output should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Level1>
    Text1
    <Level2>
        Text2
        <Level3>
            Text4
        </Level3>
    </Level2>

    <Level2>
        Text3
        <Level3>
            Text5
        </Level3>
    </Level2>
</Level1>

I already tried to use templates and call them recursively but with no success. Maybe there is a easy way to tackle this kind of problem. Thank you for your help in advance!

Upvotes: 0

Views: 134

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

You can use a key to identify Data elements by the id attribute and then follow references using the key function on the tokenize(@referenceID, '\s+') sequence:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="ref" match="Data" use="@id"/>

  <xsl:template match="*[Data[@id]]">
      <xsl:apply-templates select="key('ref', '1')"/>
  </xsl:template>

  <xsl:template match="Data">
      <xsl:param name="level" as="xs:integer" select="1"/>
      <xsl:element name="Level{$level}">
          <xsl:apply-templates select="node(), key('ref', tokenize(@referenceID, '\s+'))">
              <xsl:with-param name="level" select="$level + 1"/>
          </xsl:apply-templates>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

That gives the right structure http://xsltfiddle.liberty-development.net/gWcDMek/2, identation with mixed contents is difficult.

Upvotes: 1

Related Questions