Использование :
/*/store[not(book[not(@id = /*/booklist/*/@id)])]
При применении к этому документу XML (предоставленный, правильно сформированный, обернув его одним верхним элементом):
<t>
<store>
<book id="b1"></book>
<book id="b2"></book>
</store>
<store>
<book id="b2"></book>
<book id="b4"></book>
</store>
<booklist>
<book id="b1"></book>
<book id="b2"></book>
<book id="b3"></book>
</booklist>
</t>
выбран необходимый элемент stor
:
<store>
<book id="b1"/>
<book id="b2"/>
</store>
Проверка с использованием XSLT в качестве хоста XPath :
<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="/">
<xsl:copy-of select=
"/*/store[not(book[not(@id = /*/booklist/*/@id)])]"/>
</xsl:template>
</xsl:stylesheet>
, когда это XSLT-преобразование применяется к вышеуказанному XML-документу, получается нужный, правильный результат :
<store>
<book id="b1"/>
<book id="b2"/>
</store>
Объяснение :
Выражение:
/*/store[not(book[not(@id = /*/booklist/*/@id)])]
означает:
Выбрать все store
элементов (дочерних элементов верхнего элемента), чтобы не было даже одного book
(дочерний) в них, чье значение атрибута id
является одним из id
значений атрибутов book
s (дочерних элементов) booklist
.