父子数据XSLT递归模板 [英] xslt recursive template on parent-child data
问题描述
我想环绕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}&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屋!