开发者

How to convert flat list to the tree

开发者 https://www.devze.com 2023-01-08 14:41 出处:网络
I have the following xml: <root> <Element1> <Hierarchy attr=\"value\"/> <Hierarchy attr=\"value\"/>

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

精彩评论

暂无评论...
验证码 换一张
取 消