XSL:如何从xml获取父子数据树

时间:2014-11-27 12:02:15

标签: xml xslt treeview

我有父母和孩子的以下xml结构,我想用xsl转换在html中创建一个树。祖先是最高的父母。

 <test>
  <id>A</id>
  <parendid></parendid>
  <ancestorid></ancestorid>
 </test>
 <test>
  <id>B</id>
  <parendid>A</parendid>
  <ancestorid>A</ancestorid>
 </test>
 <test>
  <id>C</id>
  <parendid>B</parendid>
  <ancestorid>A</ancestorid>
 </test>
 <test>
  <id>D</id>
  <parendid></parendid>
  <ancestorid></ancestorid>
 </test>
 <test>
  <id>E</id>
  <parendid>D</parendid>
  <ancestorid>D</ancestorid>
 </test>
 <test>
  <id>F</id>
  <parendid>D</parendid>
  <ancestorid>D</ancestorid>
 </test>

我希望有这种结构。

 A
 +---B
 |   +---C
 D
 +---E
 +---F

 <html>
 <body>
 <div id="treeview">
    <ul>
        <li>A
            <ul>
                <li>B
                    <ul>
                        <li>C</li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>D
            <ul>
                <li>E</li>
                <li>F</li>
            </ul>
        </li>
    </ul>
 </div>
 </body>
 </html>

我是xsl的新手,我需要你的帮助。

由于

托马斯

1 个答案:

答案 0 :(得分:0)

使用html结果简单实现(仅用于示例):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" version="4.0" encoding="utf-8" indent="yes"/>

<xsl:key name="children" match="test" use="parendid" />

<xsl:template match="/root">
    <!-- for each root -->
    <xsl:for-each select="key('children', '')">
        <xsl:call-template name="traverse">
            <xsl:with-param name="level" select="0"/>   
            <xsl:with-param name="parent" select="id"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>   

<xsl:template name="traverse">
    <xsl:param name="level"/>
    <xsl:param name="parent"/>
    <div style="padding-left:{$level*10}">
        <xsl:value-of select="id"/>
    </div>
    <!-- recursively traverse all descendants using parentid element for building parent-child link -->
    <xsl:for-each select="key('children', id)">
        <xsl:call-template name="traverse">
            <xsl:with-param name="level" select="$level + 1"/>
            <xsl:with-param name="parent" select="id"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

此处为密钥(&#39; children&#39;,&#39;&#39;)=所有具有空父级的元素,即&#34;根&#34;。

此处的密钥用于优化,因为在没有密钥的情况下,由于嵌套的for循环,大型xml文件的性能非常糟糕。

P.S。我已经用root元素包装测试节点,以使xml格式良好。