我有以下XML:
<bookstore>
<books>
<book name="book1" title="Title 1" author="Author 1"/>
<book name="book2" title="Title 2" author="Author 2"/>
<book name="book3" title="Title 1" author="Author 2"/>
</books>
<myBooks>
<book name="Test1" title="Title 1" author="Author 1"/>
<book name="Test2" title="Title 2" author="Author 1"/>
<book name="Test3" title="Title 1" author="Author 2"/>
</myBooks>
</bookstore>
我希望name
中book
myBooks
book
books
"Test2"
("Title 2", "Author 1")
中的books
{标题和作者}。{/ p} >
因此,对于该示例,我想检索:图书//myBooks/book[not(@title = //books/book/@title and @author = //books/book/@author)]
,因为and
中不存在{{1}}对。
到目前为止,我有:
{{1}}
但是,当然,在这种情况下,上述XPath不起作用,因为存在组合(“标题2”,“作者1”)(来自“book2”和“book1”)。
如何在同一节点上应用{{1}}运算符?
答案 0 :(得分:11)
这取决于XPath的版本。
您无法在单个XPath 1.0表达式中执行此操作,因为它需要类似
的结构/bookstore/myBooks/book[/bookstore/books/book[
@title = _outer-predicate_/@title and
@author = _outer-predicate_/@author]]/@name
即。您需要捕获外部谓词所测试的书籍,以便将其与内部谓词进行比较。纯XPath 1.0不支持此功能,您必须自己迭代myBooks
的内容(例如使用xsl:for-each
,因为您已标记了您的问题&# 34; XSLT&#34)
在XPath 2.0中,可以在一个带有显式量词的表达式中
/bookstore/myBooks/book[not(some $book in /bookstore/books/book satisfies
($book/@author = @author and $book/@title = @title))]/@name
答案 1 :(得分:3)
假设XSLT我会定义一个键<xsl:key name="book" match="books/book" use="concat(@title, '|', @author)"/>
,然后在谓词中你可以检查[not(key('book', concat(@title, '|', @author)))]
。
答案 2 :(得分:2)
您可以使用concat()
连接属性值并进行比较:
//myBooks/book[not(concat(@*[name() = "title" or name() = "author"], ",") = concat(//books/book/@*[name() = "title" or name() = "author"], ","))]
对于book
中的每个myBook
,它会获得title
和author
属性的串联,并将其与book
中books
的相同级联进行比较1}}。
演示(使用xmllint
):
$ xmllint input.xml --xpath '//myBooks/book[not(concat(@*[name() = "title" or name() = "author"], ",") = concat(//books/book/@*[name() = "title" or name() = "author"], ","))]'
<book name="Test2" title="Title 2" author="Author 1"/>