I have the following xml:
<root>
<Element1>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
</Element1>
<AnotherElement>
<YetAnotherElement>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
<Hierarchy attr="value"/>
</YetAnotherElement>
</AnotherElement>
<开发者_StackOverflow社区;/root>
How to convert 'Hierarchy' messages into tree? i.e.
<root>
<Element1>
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value"/>
</Hierarchy>
</Hierarchy>
</Hierarchy>
</Element1>
<AnotherElement>
<YetAnotherElement>
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value"/>
</Hierarchy>
</Hierarchy>
</Hierarchy>
</YetAnotherElement>
</AnotherElement>
</root>
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hierarchy[position() != 1]"/>
<xsl:template match="Hierarchy[1]">
<xsl:apply-templates select="." mode="Hierarchy"/>
</xsl:template>
<xsl:template match="Hierarchy" mode="Hierarchy">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="following-sibling::Hierarchy[1]" mode="Hierarchy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result:
<root>
<Element1>
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value"></Hierarchy>
</Hierarchy>
</Hierarchy>
</Hierarchy>
</Element1>
<AnotherElement>
<YetAnotherElement>
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value">
<Hierarchy attr="value"></Hierarchy>
</Hierarchy>
</Hierarchy>
</Hierarchy>
</YetAnotherElement>
</AnotherElement>
</root>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:if test="name() != 'Hierarchy'">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="Hierarchy">
<xsl:if test="position() = 1">
<xsl:call-template name="makeTree">
<xsl:with-param name="elem" select="." />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="makeTree">
<xsl:param name="elem" />
<xsl:copy>
<xsl:apply-templates select="$elem/@*" />
<xsl:if test="count($elem/following-sibling::node()) > 0">
<xsl:call-template name="makeTree">
<xsl:with-param name="elem" select="$elem/following-sibling::node()[1]" />
</xsl:call-template>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
精彩评论