式で div の下のすべてを選択する必要がありますが、そうではないノードが選択されますa
。ツリー構造は同じままでなければなりません。
使用:
/div/descendant::node()[not(self::a)]
div
これは、(子孫) ではない最上位要素の子孫を選択しますa
。
XSLT ベースの検証:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="/div/descendant::node()[not(self::a)]">
<xsl:value-of select="concat('
', position(), '. "')"/>
<xsl:copy-of select="."/>"
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<div>
<span>
<a>lala</a>
</span>
</div>
XPath 式が評価され、選択されたすべてのノードが適切なフォーマットで出力され、見やすくなります。
1. "
"
2. "<span>
<a>lala</a>
</span>"
3. "
"
4. "lala"
5. "
"
6. "
"
ご覧のとおり、6 つのノード (1 つのspan
要素、4 つの空白のみのテキスト ノード、1 つの非空白のみのテキスト ノード) が選択されていますが、いずれもa
.
更新:
コメントで、OP は、実際には XML ドキュメントを別のドキュメントに変換することを望んでいることを明らかにしました。このドキュメントでa
は、a の子孫div
は省略されています。
そのような変換の 1 つを次に示します。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div//a"/>
</xsl:stylesheet>
この変換が同じ XML ドキュメント (上記) に適用されると、(私が推測するに) 必要な結果が生成されます。
<div>
<span/>
</div>
div
子孫を持つany の子孫のみを生成したい場合はa
、ほぼ同じ変換が必要です。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[.//a]"><xsl:apply-templates/></xsl:template>
<xsl:template match="div//a"/>
</xsl:stylesheet>
これを上記と同じ XML ドキュメントに適用した結果は次のとおりです。
<span/>