代码之家  ›  专栏  ›  技术社区  ›  Michael Pakhantsov

如何将平面列表转换为树

  •  1
  • Michael Pakhantsov  · 技术社区  · 14 年前

    我有以下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 回复  |  直到 14 年前
        1
  •  4
  •   user357812 user357812    14 年前

    此样式表:

    <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>
    
        2
  •  0
  •   svick Randy Levy    14 年前
    <?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>