XSLT:选择id属性与指定id值匹配的元素
处理嵌套XML导航的XSLT解决方案
嘿,作为刚接触XML和XSLT的新手,遇到嵌套结构的转换瓶颈太正常啦!我来帮你捋捋思路——你给出的这种多层级<item>嵌套的导航结构,最适合用递归模板来处理,这也是XSLT处理层级节点的核心技巧之一。
先把你提供的XML结构格式化一下,方便看清楚层级:
<navigation> <item id="1"> <item id="6" /> <item id="7"> <item id="18" /> <item id="19" /> </item> <item id="8" /> <item id="9" /> </item> <item id="2"> <item id="10" /> <item id="11" /> <!-- 省略其他子节点 --> </item> </navigation>
通用递归转换示例(以生成HTML无序列表为例)
假设你想把这个嵌套导航转换成HTML的层级列表,下面是一份可直接参考的XSLT代码,我会逐部分解释:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配XML根节点,初始化输出结构 --> <xsl:template match="/"> <html> <body> <!-- 最外层的无序列表 --> <ul class="main-nav"> <!-- 调用处理item的模板,从navigation下的第一层item开始 --> <xsl:apply-templates select="navigation/item"/> </ul> </body> </html> </xsl:template> <!-- 核心:处理item节点的递归模板 --> <xsl:template match="item"> <li> <!-- 输出当前item的ID,你可以换成实际的导航文本/链接 --> <span>导航项 ID: <xsl:value-of select="@id"/></span> <!-- 如果当前item有子item,就递归生成子列表 --> <xsl:if test="item"> <ul class="sub-nav"> <!-- 再次调用当前模板,处理子item --> <xsl:apply-templates select="item"/> </ul> </xsl:if> </li> </xsl:template> </xsl:stylesheet>
关键知识点解析
- 递归模板的作用:
match="item"的模板会处理每一个<item>节点,当发现当前节点有子<item>时,会再次调用自身生成嵌套的子列表,完美适配任意深度的层级结构。 - 自动终止递归:当某个
<item>没有子节点时,<xsl:if test="item">的条件不成立,就不会生成子列表,递归自动终止,不用担心死循环。 - 灵活调整输出:如果你的XML里
<item>有其他属性(比如name、url),直接替换输出内容即可,比如改成:<a href="{@url}"><xsl:value-of select="@name"/></a>
新手常见坑提醒
- 一定要记得声明XSLT的命名空间
xmlns:xsl="http://www.w3.org/1999/XSL/Transform",这是XSLT文件的必要配置。 - 如果需要处理特殊的节点逻辑(比如跳过某个ID的item、给特定层级加样式),可以在模板里添加
<xsl:if>或<xsl:choose>来判断。
如果你的转换需求不是生成HTML列表(比如要生成纯文本、JSON或者其他格式),可以把具体需求说出来,我再帮你调整模板~
内容的提问来源于stack exchange,提问作者Mateusz Sarnowski
相关产品推荐
相关产品推荐

