来自 XML 的 XSL 树构造

XSL tree construction from XML

我从几个 days/week 开始就崩溃了,所以现在我想是时候问一些新的建议了。

*这是我在 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>

我选择对 "tree" 和第一个 "item" 元素进行硬编码,以开始结构良好的结构。

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

我尝试了很多东西:

  1. child/parent 属性的条件测试 => 不起作用,因为没有对每个 "row" ?
  2. 应用测试
  3. 使用变量存储父属性的值 => 不起作用,因为变量的值在声明后无法更改

所以我真的不知道如何找到构建这棵树的解决方案:(

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

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

此致

在您的模板匹配 / 中,您应该首先 select 仅 row 部门级别为 0

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

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

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

还要注意使用 "Attribute Value Templates" 来设置 item 元素的属性。