父子数据XSLT递归模板 [英] xslt recursive template on parent-child data

查看:169
本文介绍了父子数据XSLT递归模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想环绕XSLT我的脑海里。 许多问题在这里对计算器的帮助( XSLT模板和递归 XSLT for-each循环,过滤器基于可变 ),但我还是有点疑惑。 我想我的思想模板的功能  (我怎么知道我的XSL是高效率和美丽?

I'm trying to wrap my mind around xslt. A number of questions here on stackoverflow help ( XSLT templates and recursion and XSLT for-each loop, filter based on variable ) but I'm still kinda puzzled. I guess I'm "thinking of template as functions" ( How do I know my XSL is efficient and beautiful? )

反正...我的数据是

<Entities>
    <Entity ID="8" SortValue="0" Name="test" ParentID="0" />
    <Entity ID="14" SortValue="2" Name="test2" ParentID="8" />
    <Entity ID="16" SortValue="1" Name="test3" ParentID="8" />
    <Entity ID="17" SortValue="3" Name="test4" ParentID="14" />
    <Entity ID="18" SortValue="3" Name="test5" ParentID="0" />
</Entities>

我想作为输出基本上是一个树状

What I'd like as output is basically a "treeview"

<ul>
    <li id="entity8">
        test
        <ul>
            <li id="entity16">
                test3
            </li>
            <li id="entity14">
                test2
                <ul>
                    <li id="entity17">
                        test4
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li id="entity18">
        test5
    </li>
</ul>

在XSLT我到目前为止是错误的,因为它肯定会认为的模板,功能,也引发对执行一个StackOverflowException(:-))

The XSLT I have so far is wrong in that it definitely "thinks of templates as functions" and also throws a StackOverflowException (:-)) on execution

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="Entities">
        <ul>
            <li>
                <xsl:value-of select="local-name()"/>
                <xsl:apply-templates/>
            </li>
        </ul>
    </xsl:template>

    <xsl:template match="//Entities/Entity[@ParentID=0]">
        <xsl:call-template name="recursive">
            <xsl:with-param name="parentEntityID" select="0"></xsl:with-param>
        </xsl:call-template>
     </xsl:template>

    <xsl:template name="recursive">
        <xsl:param name="parentEntityID"></xsl:param>
        <xsl:variable name="counter" select="//Entities/Entity[@ParentID=$parentEntityID]"></xsl:variable>

        <xsl:if test="count($counter) > 0">
            <xsl:if test="$parentEntityID > 0">
            </xsl:if>
                <li>
                    <xsl:variable name="entityID" select="@ID"></xsl:variable>
                    <xsl:variable name="sortValue" select="@SortValue"></xsl:variable>
                    <xsl:variable name="name" select="@Name"></xsl:variable>
                    <xsl:variable name="parentID" select="@ParentID"></xsl:variable>                    

                    <a href=?ID={$entityID}&amp;ParentEntityID={$parentID}">
                        <xsl:value-of select="$name"/>
                    </a>

                    <xsl:call-template name="recursive">
                        <xsl:with-param name="parentEntityID" select="$entityID"></xsl:with-param>
                    </xsl:call-template>

                </li>           
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

我知道如何code,没有问题要做到这一点。 这一次,虽然,我正在寻找在XSLT的解决方案,并为任何帮助将不胜AP preciated。

I know how to do this by code, no problem. This time, though, I'm looking for a solution in xslt and for that any help would be greatly appreciated.

推荐答案

虽然调用模板和命名模板是语言的一个非常有用的功能,如果你发现自己$ P $他们pferring到适用-模板这可能是一个迹象,表明你还想着在功能,而不是模板。尤其是这样,如果你在一个命名模板做的第一件事就是选择要操作节点集。

Although call-template and named templates are a very useful feature of the language, if you find yourself preferring them to apply-templates it may be a sign that you are still thinking in functions rather than templates. This is particularly true if the first thing you do in a named template is select a nodeset on which to operate.

下面是你正在尝试做一下简单的版本。

Here is a simple version of what you are trying to do.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:template match="/">
        <ul>
           <xsl:apply-templates select="Entities/Entity[@ParentID=0]" />
        </ul>
    </xsl:template>

    <xsl:template match="Entity">
        <li>
           <xsl:value-of select="@Name" />
           <xsl:apply-templates select="../Entity[@ParentID=current()/@ID]" />
        </li>
    </xsl:template>
</xsl:stylesheet>

请注意,没有必要在计数器,作为母的值提供了必要的上下文。

Note that there is no need for the counter, as the value of the "parent" provides the necessary context.

另外请注意,所有实体的行为以同样的方式,无论在哪里,他们都在树上,它们包含 @Name 值,以及模板适用于任何实体对象的@ParentID当前水平的@ID相匹配。

Also note that all Entities behave in the same way, regardless of where they are in the tree, they contain their @Name value, and apply the template to any Entity objects whose @ParentID matches the @ID of the current level.

这篇关于父子数据XSLT递归模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆