我已经看到了转换“邻接模型”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" 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标签不应该存在。我可以看到它为什么会发生但只是不确定如何更改代码来修复它。
感谢。
答案 0 :(得分:3)
已更新以反映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>
如果您对如何创建列表感到困扰,请在W3School处尝试。
答案 1 :(得分:2)
您非常接近,只需将<xsl:variable name="ID" select="@Id"/>
和<xsl:apply-templates select="//row[@ParentId=$ID]"/>
移到<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>
这也会删除顶级<ul>
<li rel="2">