【发布时间】:2012-05-25 23:21:23
【问题描述】:
鉴于此 XML
<Xml> <Thing id="1" > <Foo id="11" parentId="12"/> <Foo id="12"/> </Thing> <Thing id="2" parentId="1" /> <Thing id="3" parentId="2" /> <Thing id="4"> <Foo id="11" parentId="15"/> <Foo id="12" parentId="14"/> <Foo id="13" parentId="11"/> <Foo id="14" parentId="15"/> <Foo id="15"/> </Thing> </Xml>
我想抓取所有兄弟姐妹的集合,并将它们组合成自己的层次结构。
每个具有 parentId 值的“事物”节点都应该嵌套在相应的事物节点下。 每个具有 parentId 值的“Foo”节点都应该嵌套在相应的 Foo 节点下——但只能嵌套在其兄弟节点内。该示例有两组 Foo 兄弟姐妹。
我正在尝试创建这个:
<Xml> <Thing id="1" > <Foo id="12"> <Foo id="11" parentId="12"/> </Foo> <Thing id="2" parentId="1" > <Thing id="3" parentId="2" /> </Thing> </Thing> <Thing id="4" > <Foo id="14" parentId="12"> <Foo id="12" parentId="14"/> </Foo> <Foo id="15"> <Foo id="11" parentId="15"> <Foo id="13" parentId="11"/> </Foo> </Foo> </Thing> </Xml>
这个例子很接近: How can I use XSLT 1.0 to add structure to a non-heirarchal XML file?
我使用身份模板来保留所有节点和属性。然后我想要一个覆盖模板来匹配所有具有兄弟姐妹(后面或前面)的节点,以便兄弟姐妹的 @parentId 值等于我的 @id 值。我最接近的方法是硬编码要匹配的 id/parentId 值。
<?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"/> <!-- override identity rule with template to match on a node who has siblings, where sibling/@parentId == ./@id --> <xsl:template match="node()[@id='1' and (preceding-sibling::*[@parentId = 1] or following-sibling::*[@parentId = 1])]"> <captured> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </captured> </xsl:template> <!-- identity rule --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
我看不到如何根据 parentId 值获取当前节点 @id 值以用于 Xpath 匹配兄弟的谓词中。
然后我想在它下面嵌套当前节点兄弟姐妹,其中兄弟姐妹@ParentId 等于我的@id。
【问题讨论】:
-
在提供的 XML 文档中存在一个细微的错误——一对无法访问的
Foo元素形成了一个闭合电路并且不能成为层次结构的一部分。请纠正。不管这个我+1这个问题,因为它很有趣。 -
已纠正错误。谢谢。对不起。
标签: xslt