Xslt 将XML邻接列表模型规范化为HTML树列表
我见过转换“邻接模型”XML的例子,但没有一个能很好地用于ul/li项目符号列表。有人能给我一个提示吗?如果该解决方案能够支持典型的邻接模型需求并处理多层嵌套/递归,那就太好了 如果XML为:Xslt 将XML邻接列表模型规范化为HTML树列表,xslt,Xslt,我见过转换“邻接模型”XML的例子,但没有一个能很好地用于ul/li项目符号列表。有人能给我一个提示吗?如果该解决方案能够支持典型的邻接模型需求并处理多层嵌套/递归,那就太好了 如果XML为: <?xml version="1.0" encoding="ISO-8859-1"?> <root> <row Id="2" Name="data" /> <row Id="3" Name="people" /> <row Id="4" N
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<row Id="2" Name="data" />
<row Id="3" Name="people" />
<row Id="4" Name="person" ParentId="3" />
<row Id="6" Name="folder" ParentId="2" />
<row Id="7" Name="thing" ParentId="3" />
<row Id="8" Name="web" />
<row Id="9" Name="link" ParentId="8" />
</root>
我用的是:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<ul id="someid" class="menu">
<xsl:apply-templates select="root/row[not(@ParentId)]"/>
</ul>
</xsl:template>
<xsl:template match="row">
<ul>
<li>
<xsl:variable name="ID" select="@Id"/>
<xsl:attribute name="rel">
<xsl:value-of select="@Id"/>
</xsl:attribute>
<xsl:value-of select="@Name"/>
<xsl:apply-templates select="//row[@ParentId=$ID]"/>
</li>
</ul>
</xsl:template>
</xsl:stylesheet>
-
然后我得到:
<ul id="someid" class="menu">
<ul>
<li rel="2">
data<ul>
<li rel="6">folder</li>
</ul>
</li>
</ul>
<ul>
<li rel="3">
people
<ul>
<li rel="4">person</li>
</ul><ul>
<li rel="7">thing</li>
</ul>
</li>
</ul>
<ul>
<li rel="8">
web<ul>
<li rel="9">link</li>
</ul>
</li>
</ul>
</ul>
-
人
人
事情
-
网络
链接
请注意,“人”和“物”之间额外的闭合/打开ul标签-不应存在。我可以理解为什么会发生这种情况,但不知道如何更改代码来修复它
谢谢。你真的很接近了,你只需要把你的
和你的
移到你的声明之外
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<ul id="someid" class="menu">
<xsl:apply-templates select="root/row[not(@ParentId)]"/>
</ul>
</xsl:template>
<xsl:template match="row">
<xsl:variable name="ID" select="@Id"/>
<li>
<xsl:attribute name="rel">
<xsl:value-of select="@Id"/>
</xsl:attribute>
<xsl:value-of select="@Name"/>
</li>
<xsl:if test="//row[@ParentId=$ID]">
<ul>
<xsl:apply-templates select="//row[@ParentId=$ID]"/>
</ul>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这就产生了我认为你正在寻找的结果
<ul id="someid" class="menu">
<li rel="2">data</li>
<ul>
<li rel="6">folder</li>
</ul>
<li rel="3">people</li>
<ul>
<li rel="4">person</li>
<li rel="7">thing</li>
</ul>
<li rel="8">web</li>
<ul>
<li rel="9">link</li>
</ul>
</ul>
这还将删除顶层之前的额外
,以反映OP新请求
这是一个递归模板,它按照W3C规范中的定义生成一个符合HTML的嵌套列表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/root">
<ul id="someid" class="menu">
<xsl:apply-templates select="row[not(@ParentId)]"/>
</ul>
</xsl:template>
<xsl:template match="row">
<li rel="{@Id}">
<xsl:value-of select="@Name"/>
<xsl:if test="count(../row[@ParentId=current()/@Id])>0">
<ul>
<xsl:apply-templates select="../row[@ParentId=current()/@Id]"/>
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
应用于此输入:
<root>
<row Id="1" Name="data" />
<row Id="2" Name="data" />
<row Id="3" Name="people" />
<row Id="4" Name="person" ParentId="3" />
<row Id="6" Name="folder" ParentId="2" />
<row Id="7" Name="thing" ParentId="3" />
<row Id="8" Name="web" />
<row Id="9" Name="link" ParentId="8" />
<row Id="10" Name="anotherone" ParentId="9" />
<row Id="11" Name="anotherone" ParentId="9" />
<row Id="12" Name="anotherone" ParentId="9" />
<row Id="13" Name="anotherone" ParentId="3" />
</root>
产生:
<ul id="someid" class="menu">
<li rel="1">data</li>
<li rel="2">data<ul>
<li rel="6">folder</li>
</ul>
</li>
<li rel="3">people<ul>
<li rel="4">person</li>
<li rel="7">thing</li>
<li rel="13">anotherone</li>
</ul>
</li>
<li rel="8">web<ul>
<li rel="9">link<ul>
<li rel="10">anotherone</li>
<li rel="11">anotherone</li>
<li rel="12">anotherone</li>
</ul>
</li>
</ul>
</li>
</ul>
数据
文件夹
人们
人
事情
另一个
web
链接
- 另一个
- 另一个
- 另一个
如果您在如何创建列表方面遇到困难,请尝试使用。这是上面的列表,但在人和物之间没有额外的/ul标签。我不认为这个列表在HTML中是有效的,只要这些标签存在?i、 e.人和物项是兄弟项,它们都是“人”项的子项。这对浏览器没有多大区别,这是正确的。不过,您会在我的答案中找到创建嵌套列表的正确方法。:)谢谢。将尽快验证并标记为答案。欢迎您。我用MSXSL 4.5.0测试了XSLT1.0,效果很好。非常感谢。此输出HTML看起来确实不像正确的HTML,即使浏览器仍将显示列表。@empo-我明白你的意思-我试图尽可能少地偏离OP提供的输出,但内部可以是- 的子项,这是更好的形式。工作起来很有魅力,可以处理递归(这是我应该提到的!!)+1表示初始递归性(OP没有提到)。关于错误的HTML,你离正确的代码不远了。好吧-大家能不能别再表现得太棒了,我开始觉得自己很愚蠢:)