如何将平面列表转换为树

时间:2010-07-20 12:59:33

标签: xml xslt

我有以下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>
</root>

如何将“层次结构”消息转换为树?即。

<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>

2 个答案:

答案 0 :(得分:4)

此样式表:

<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>

结果:

<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>

答案 1 :(得分:0)

<?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>