这应该很简单!我有一个包含菜单层次结构的XML文档:
<?xml version="1.0" encoding="utf-8"?>
<menu page_id="18" language="en-GB">
<item id="1" child_of="0">
<menu_order>1</menu_order>
<title><![CDATA[Home]]></title>
</item>
<item id="18" child_of="0">
<title><![CDATA[Page One]]></title>
<submenu child_of="18">
<item id="20" child_of="18">
<title><![CDATA[Sub Menu One]]></title>
<submenu child_of="20">
<item id="26" child_of="20">
<title><![CDATA[SubMenu 1-1]]></title>
</item>
<item id="27" child_of="20">
<title><![CDATA[SubMenu 1-2]]></title>
</item>
</submenu>
</item>
<item id="21" child_of="18">
<title><![CDATA[Sub Menu Two]]></title>
<submenu child_of="21">
<item id="28" child_of="21">
<title><![CDATA[SubMenu 2-1]]></title>
</item>
<item id="29" child_of="21">
<title><![CDATA[SubMenu 2-2]]></title>
<submenu child_of="29">
<item id="32" child_of="29">
<title><![CDATA[SubMenu 2-2-1]]></title>
</item>
<item id="33" child_of="29">
<title><![CDATA[SubMenu 2-2-2]]></title>
</item>
</submenu>
</item>
<item id="30" child_of="21">
<title><![CDATA[SubMenu 2-3]]></title>
</item>
<item id="31" child_of="21">
<title><![CDATA[SubMenu 2-4]]></title>
</item>
</submenu>
</item>
<item id="22" child_of="18">
<title><![CDATA[Sub Menu Three]]></title>
</item>
</submenu>
</item>
<item id="19" child_of="0">
<title><![CDATA[Page Two]]></title>
</item>
</menu>
我需要将其转换为HTML列表,其中(1)如果活动/单击菜单项有子菜单,则显示其子菜单(仅菜单的子菜单项)。例如,点击item id = "18"应该会得到这样的结果:
<ul>
<li id="1">Home</li>
<li id="18">Page One
<ul>
<li id="20">Sub Menu One</li>
<li id="21">Sub Menu Two</li>
<li id="22">Sub Menu Three</li>
</ul>
</li>
<li id="19">Page Two</li>
</ul>
或者(2)如果活动菜单项有祖先,它在结构中呈现它的所有直接兄弟和祖先。例如,点击item id="33"应该是这样的:
<ul>
<li id="1">Home</li>
<li id="18">Page One<ul>
<li id="20">Sub Menu One</li>
<li id="21">Sub Menu Two<ul>
<li id="28">SubMenu 2-1</li>
<li id="29">SubMenu 2-2
<ul>
<li id="32">SubMenu 2-2-1</li>
<li id="33">SubMenu 2-2-2</li>
</ul>
</li>
<li id="30">SubMenu 2-3</li>
<li id="31">SubMenu 2-4</li>
</ul>
</li>
<li id="22">Sub Menu Three</li>
</ul>
</li>
<li id="19">Page Two</li>
</ul>
我的问题是我的XSL样式表生成了一个包含两个祖先子菜单的列表!请帮忙……我已经做了几个小时了!下面是我的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<!-- The DOM ID of the active menu item -->
<xsl:param name="activeItemID"/>
<xsl:template match="text()">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="menu">
<ul>
<xsl:choose>
<xsl:when test="//item[@id = $activeItemID]/@child_of = '0'">
<xsl:choose>
<xsl:when test="//submenu[@child_of = $activeItemID]/node()">
<xsl:apply-templates
select="//item[@child_of = '0'] | //submenu[@child_of = $activeItemID]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="//item[@child_of = '0']"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="//submenu[@child_of = $activeItemID]/node()">
<xsl:apply-templates
select="//item[@child_of = '0'] | //submenu[@child_of = $activeItemID]/ancestor-or-self::submenu/item"
/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates
select="//item[@child_of = '0'] | //item[@id = $activeItemID]/ancestor-or-self::submenu"
/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</ul>
</xsl:template>
<xsl:template match="item">
<li>
<xsl:value-of select="title" disable-output-escaping="no"/>
<xsl:apply-templates select="submenu[@child_of = $activeItemID]"/>
</li>
</xsl:template>
<xsl:template match="submenu">
<ul>
<xsl:apply-templates select="item[@child_of = $activeItemID]">
<xsl:sort select="menu_order" data-type="number"/>
</xsl:apply-templates>
</ul>
</xsl:template>
</xsl:stylesheet>
这个XSLT应该可以完成您想要做的事情:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<!-- The DOM ID of the active menu item -->
<xsl:param name="activeItemID" />
<xsl:template match="menu | submenu">
<ul>
<xsl:apply-templates select="item" />
</ul>
</xsl:template>
<xsl:template match="item">
<li id="{@id}">
<xsl:value-of select="title" />
<xsl:apply-templates select="submenu[..//@id = $activeItemID]"/>
</li>
</xsl:template>
</xsl:stylesheet>
在参数值为18的示例输入上运行时,它产生:
<ul>
<li id="1">Home</li>
<li id="18">
Page One<ul>
<li id="20">Sub Menu One</li>
<li id="21">Sub Menu Two</li>
<li id="22">Sub Menu Three</li>
</ul>
</li>
<li id="19">Page Two</li>
</ul>
当参数值为33时,它产生:
<ul>
<li id="1">Home</li>
<li id="18">
Page One<ul>
<li id="20">Sub Menu One</li>
<li id="21">
Sub Menu Two<ul>
<li id="28">SubMenu 2-1</li>
<li id="29">
SubMenu 2-2<ul>
<li id="32">SubMenu 2-2-1</li>
<li id="33">SubMenu 2-2-2</li>
</ul>
</li>
<li id="30">SubMenu 2-3</li>
<li id="31">SubMenu 2-4</li>
</ul>
</li>
<li id="22">Sub Menu Three</li>
</ul>
</li>
<li id="19">Page Two</li>
</ul>
XSLT有一些排序逻辑,但是用于排序的元素似乎只出现在源XML中的一个地方。那是你想用的东西吗?为了简单起见,您是否省略了源XML中的大部分menu_order
元素?