从XML构建XSL树

时间:2018-07-25 10:31:59

标签: xml xslt dhtmlx

从几天/一周开始,我就伤脑筋了,所以现在我想是时候问一些新建议了。

*这是我在XML / XSL中的第一个项目,我会尽量做到最清晰

我从SQL查询中获得了XML的输出,输出看起来像这样:

<row DEPARTMENT="SOCIETY" DEPARTMENT_LEVEL="0" CHILD_DEPARTMENT="1111" PARENT_DEPARTMENT="1111"/> 

<row DEPARTMENT="Boss" DEPARTMENT_LEVEL="1" CHILD_DEPARTMENT="2222" PARENT_DEPARTMENT="1111"/>

<row DEPARTMENT="Second Boss" DEPARTMENT_LEVEL="1" CHILD_DEPARTMENT="3333" PARENT_DEPARTMENT="1111"/>

<row DEPARTMENT="Secretary" DEPARTMENT_LEVEL="1" CHILD_DEPARTMENT="4444" PARENT_DEPARTMENT="1111"/>

<row DEPARTMENT="Desk" DEPARTMENT_LEVEL="2" CHILD_DEPARTMENT="5555" PARENT_DEPARTMENT="4444"/>

<row DEPARTMENT="Chief" DEPARTMENT_LEVEL="3" CHILD_DEPARTMENT="6666" PARENT_DEPARTMENT="5555"/>

<row DEPARTMENT="post1" DEPARTMENT_LEVEL="4" CHILD_DEPARTMENT="7777" PARENT_DEPARTMENT="6666"/>

<row DEPARTMENT="post2" DEPARTMENT_LEVEL="4" CHILD_DEPARTMENT="8888" PARENT_DEPARTMENT="6666"/>

<row DEPARTMENT="post3" DEPARTMENT_LEVEL="4" CHILD_DEPARTMENT="9999" PARENT_DEPARTMENT="6666"/>

然后我正在搜索使用XSL构建树:

<xsl:template match='/'>
<html>
<body>
    <ul>
    <tree id='0'>
        <li><item>
        <xsl:attribute name ='id'>1111</xsl:attribute>
        <xsl:attribute name ='text'>Society</xsl:attribute>
        <xsl:apply-templates select='//row' />
        </item></li>
    </tree>
    </ul>
</body>
</html>
</xsl:template>
<xsl:template match='//row'>
<li><item>
    <xsl:attribute name ='id'>
    <xsl:value-of select='@CHILD_DEPARTMENT' />
    </xsl:attribute>
        <xsl:attribute name ='text'>
    <xsl:value-of select='@DEPARTMENT' />
    </xsl:attribute>
</item></li>
</xsl:template>

我需要获取格式良好的数据以将其放入DHTMLX树中,它必须看起来像这样:

<tree id="0">
<item id="1111" text="Society">
  <item id="2222" text="Boss"/>
  <item id="3333" text="Second Boss"/>
  <item id="4444" text="Secretary">
     <item id="5555" text="Desk">
        <item id="6666" text="Chief">
           <item id="7777" text="post1"/>
           <item id="8888" text="post2"/>
           <item id="9999" text="post3"/>
        </item>
     </item>
  </item>
</item>
</tree>

这就是我的代码所得到的:

<tree id="0">
<item id="1111" text="Society"/>
    <item id="2222" text="Boss"/>
    <item id="3333" text="Second Boss"/>
    <item id="4444" text="Secretary"/>
        <item id="5555" text="Desk"/>
        <item id="6666" text="Chief"/>
        <item id="7777" text="post1"/>
        <item id="8888" text="post2"/>
        <item id="9999" text="post3"/>
</item>
</tree>

我选择对“树”元素和第一个“项目”元素进行编码,以使结构的开始井井有条。

您可能没有注意到,这段代码中没有任何内容可以测试它是否必须是新元素还是子元素。

我尝试了很多事情,例如:

  1. 对子级/父级属性的条件测试=>不起作用,因为不对每个“行”都进行测试吗?
  2. 使用变量存储父属性的值=>无效,因为声明后不能更改变量的值

所以我真的迷失了如何找到构建此树的解决方案:(

如果有人对我有建议,那将非常有帮助!

Ps:抱歉,有些拼写错误,英语不是我的母语。

致谢

1 个答案:

答案 0 :(得分:1)

在与/相匹配的模板中,您应该首先选择部门级别为0的row个元素

<xsl:apply-templates select="//row[@DEPARTMENT_LEVEL='0']" />

然后,在与row匹配的模板中,您需要为当前行选择相关的子项

<xsl:apply-templates select="//row[@PARENT_DEPARTMENT = current()/@CHILD_DEPARTMENT and @DEPARTMENT_LEVEL = current()/@DEPARTMENT_LEVEL + 1]" />

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes" />

<xsl:template match='/'>
    <tree id='0'>
        <xsl:apply-templates select="//row[@DEPARTMENT_LEVEL='0']" />
    </tree>
</xsl:template>

<xsl:template match='//row'>
    <item>
        <xsl:attribute name ='id'>
            <xsl:value-of select='@CHILD_DEPARTMENT' />
        </xsl:attribute>
        <xsl:attribute name ='text'>
            <xsl:value-of select='@DEPARTMENT' />
        </xsl:attribute>
        <xsl:apply-templates select="//row[@PARENT_DEPARTMENT = current()/@CHILD_DEPARTMENT and @DEPARTMENT_LEVEL = current()/@DEPARTMENT_LEVEL + 1]" />
    </item>
</xsl:template>
</xsl:stylesheet>

或者,请阅读xsl:key,该信息可用于获取父级的子行

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes" />

<xsl:key name="rowsByParent" match="row" use="@PARENT_DEPARTMENT" />

<xsl:template match='/'>
    <tree id='0'>
        <xsl:apply-templates select="//row[@DEPARTMENT_LEVEL='0']" />
    </tree>
</xsl:template>

<xsl:template match='//row'>
    <item id="{@CHILD_DEPARTMENT}" text="{@DEPARTMENT}">
        <xsl:apply-templates select="key('rowsByParent', @CHILD_DEPARTMENT)[@DEPARTMENT_LEVEL = current()/@DEPARTMENT_LEVEL + 1]" />
    </item>
</xsl:template>
</xsl:stylesheet>

还请注意使用“属性值模板”来设置item元素的属性。