I would like to have xpath, that obtains nodes, that don't have ancestor, which is first descendant of specific node.
Let's assume we have xml document like this:
<a>
<b>This node</b>
<c>
<a>
<b>not this</b>
<g>
<b>not this</b>
</g>
</a>
<a>
<b>This node</b>
<c/>
</a>
</c>
</a>
<a>
<c>
<a>
<b>not this</b>
</a>
<a>
<b>This node</b>
</a>
<a>
<b>This node</b>
</a>
<a>
<b>This node</b>
</a>
</c>
</a>
<d>
<b>This node</b>
</d>
I would like to select all b nodes in document that don't have as their ancestor node //a/c/a[1].
I would like to select all b nodes in
document that don't have as their
ancestor node //a/c/a[1]
Use this XPath expression:
//b[not(ancestor::a
[parent::c[parent::a]
and
not(preceding-sibling::a)
]
)
]
This selects all b
elements in the document that don't have ancestor a
that has a parent c
that has parent a
and the a
ancestor that has parent c
is not the first a
child of its parent.
Given the following XML document (based on the provided, but made well-formed and also put identifying text in the nodes that should be selected):
<t>
<a>
<b>This node 1</b>
<c>
<a>
<b>not this</b>
<g>
<b>not this</b>
</g>
</a>
<a>
<b>This node 2</b>
<c/>
</a>
</c>
</a>
<a>
<c>
<a>
<b>not this</b>
</a>
<a>
<b>This node 3</b>
</a>
<a>
<b>This node 4</b>
</a>
<a>
<b>This node 5</b>
</a>
</c>
</a>
<d>
<b>This node 6</b>
</d>
</t>
exactly the wanted 6 b
elements are selected.
Verification using 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:copy-of select=
"//b[not(ancestor::a
[parent::c[parent::a]
and
not(preceding-sibling::a)
]
)
]
"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the above XML document, exactly the wanted b
elements are selected and copied to the output. The wanted, correct result is produced:
<b>This node 1</b>
<b>This node 2</b>
<b>This node 3</b>
<b>This node 4</b>
<b>This node 5</b>
<b>This node 6</b>