如何用XSLT将按ID关联的扁平XML转换为嵌套树层级结构
问题原因
你当前的XSLT会默认匹配并输出<root>下所有<catalogue>节点,因此会生成三个平行的<catalogue>结构,本质是没有过滤掉非顶层的节点,只需要保留没有被其他任何item的child/id引用的顶层catalogue即可。
解决方案
修改后的XSLT如下,新增了root节点匹配逻辑过滤顶层节点,同时新增key优化查找效率:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 按item的id索引catalogue节点 --> <xsl:key name="catalogueById" match="catalogue" use="item/id" /> <!-- 处理root节点,仅输出顶层(无父节点)的catalogue --> <xsl:template match="root"> <xsl:copy> <!-- 筛选条件:没有任何其他catalogue的child/id等于当前catalogue的item/id --> <xsl:apply-templates select="catalogue[not(key('catalogueById', item/id)/../item/child/id = item/id)]" /> </xsl:copy> </xsl:template> <!-- 原有catalogue嵌套逻辑保留 --> <xsl:template match="catalogue"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> <!-- 查找当前catalogue对应子节点,递归处理 --> <xsl:apply-templates select="key('catalogueById', item/child/id)" /> </xsl:copy> </xsl:template> <!-- 原有身份复制模板保留 --> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
效果说明
上述代码会先从所有catalogue中筛选出没有父节点的顶层节点(你的示例中就是item1对应的catalogue),再递归嵌套子节点,最终输出的结构完全符合预期,不会出现多余的平行catalogue节点。
内容的提问来源于stack exchange,提问作者Mebbo
相关产品推荐
相关产品推荐

