Reputation: 23
I have an XML that looks like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Report>
<BCOT>
<Detail_Collection>
<Detail>
<ElementId>Element1</ElementId>
<ParentElementId>Element0</ParentElementId>
</Detail>
<Detail>
<ElementId>Element2</ElementId>
<ParentElementId>Element1</ParentElementId>
</Detail>
<Detail>
<ElementId>Element3</ElementId>
<ParentElementId>Element2</ParentElementId>
</Detail>
<Detail>
<ElementId>Element4</ElementId>
<ParentElementId>Element3</ParentElementId>
</Detail>
<Detail>
<ElementId>Element5</ElementId>
<ParentElementId>Element3</ParentElementId>
</Detail>
<Detail>
<ElementId>Element6</ElementId>
<ParentElementId>Element1</ParentElementId>
</Detail>
<Detail>
<ElementId>Element7</ElementId>
<ParentElementId>Element6</ParentElementId>
</Detail>
<Detail>
<ElementId>Element8</ElementId>
<ParentElementId>Element7</ParentElementId>
</Detail>
<Detail>
<ElementId>Element9</ElementId>
<ParentElementId>Element8</ParentElementId>
</Detail>
<Detail>
<ElementId>Element10</ElementId>
<ParentElementId>Element9</ParentElementId>
</Detail>
<Detail>
<ElementId>Element11</ElementId>
<ParentElementId>Element10</ParentElementId>
</Detail>
<Detail>
<ElementId>Element12</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
<Detail>
<ElementId>Element13</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
<Detail>
<ElementId>Element14</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
<Detail>
<ElementId>Element15</ElementId>
<ParentElementId>Element9</ParentElementId>
</Detail>
<Detail>
<ElementId>Element16</ElementId>
<ParentElementId>Element15</ParentElementId>
</Detail>
<Detail>
<ElementId>Element17</ElementId>
<ParentElementId>Element16</ParentElementId>
</Detail>
<Detail>
<ElementId>Element18</ElementId>
<ParentElementId>Element16</ParentElementId>
</Detail>
</Detail_Collection>
</BOMConsistOfTmp>
</Report>
And I need a stylesheet to get it to look like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Report>
<BCOT>
<Detail_Collection>
<Detail>
<ElementId>Element1</ElementId>
<ParentElementId>Element0</ParentElementId>
<Detail>
<ElementId>Element2</ElementId>
<ParentElementId>Element1</ParentElementId>
<Detail>
<ElementId>Element3</ElementId>
<ParentElementId>Element2</ParentElementId>
<Detail>
<ElementId>Element4</ElementId>
<ParentElementId>Element3</ParentElementId>
</Detail>
<Detail>
<ElementId>Element5</ElementId>
<ParentElementId>Element3</ParentElementId>
</Detail>
</Detail>
</Detail>
<Detail>
<ElementId>Element6</ElementId>
<ParentElementId>Element1</ParentElementId>
<Detail>
<ElementId>Element7</ElementId>
<ParentElementId>Element6</ParentElementId>
<Detail>
<ElementId>Element8</ElementId>
<ParentElementId>Element7</ParentElementId>
<Detail>
<ElementId>Element9</ElementId>
<ParentElementId>Element8</ParentElementId>
<Detail>
<ElementId>Element10</ElementId>
<ParentElementId>Element9</ParentElementId>
<Detail>
<ElementId>Element11</ElementId>
<ParentElementId>Element10</ParentElementId>
<Detail>
<ElementId>Element12</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
<Detail>
<ElementId>Element13</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
<Detail>
<ElementId>Element14</ElementId>
<ParentElementId>Element11</ParentElementId>
</Detail>
</Detail>
</Detail>
<Detail>
<ElementId>Element15</ElementId>
<ParentElementId>Element9</ParentElementId>
<Detail>
<ElementId>Element16</ElementId>
<ParentElementId>Element15</ParentElementId>
<Detail>
<ElementId>Element17</ElementId>
<ParentElementId>Element16</ParentElementId>
</Detail>
<Detail>
<ElementId>Element18</ElementId>
<ParentElementId>Element16</ParentElementId>
</Detail>
</Detail>
</Detail>
</Detail>
</Detail>
</Detail>
</Detail>
</Detail>
</Detail_Collection>
</BOMConsistOfTmp>
</Report>
I have read that it is better to use templates when I have a recursive task, but I have never fully understood templates as opposed to for-each.
I have tried using a strategy, where I run it a fixed number of times, but I would really like it to work recursively.
Can someone help me?
Upvotes: 0
Views: 34
Reputation: 116982
This is easy to do using a key to identify each detail's children (and also the existence of a parent):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="parent" match="Detail" use="ElementId" />
<xsl:key name="child" match="Detail" use="ParentElementId" />
<xsl:template match="/Report">
<Report>
<BCOT>
<Detail_Collection>
<xsl:apply-templates select="BCOT/Detail_Collection/Detail[not(key('parent', ParentElementId))]"/>
</Detail_Collection>
</BCOT>
</Report>
</xsl:template>
<xsl:template match="Detail">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:apply-templates select="key('child', ElementId)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1