この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値を持つすべての「Thing」ノードは、対応するThingノードの下にネストする必要があります。parentId値を持つすべての「Foo」ノードは、対応するFooノードの下にネストする必要がありますが、その兄弟内にのみネストする必要があります。この例には、2セットの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>
この例は近づいています: XSLT 1.0を使用して非階層XMLファイルに構造を追加するにはどうすればよいですか?
IDテンプレートを使用して、すべてのノードと属性を保持しました。次に、兄弟の@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値に基づいてXpathマッチング兄弟の述語で使用する現在のノードの@id値を取得する方法がわかりません。
次に、現在のノードの兄弟をその下にネストします。兄弟の@ParentIdは私の@idと同じです。