简体   繁体   English

XPath中的多个条件(和运算符)

[英]Multiple conditions (and operator) in XPath

I have the following XML: 我有以下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>

I want to get all name of book in myBooks that have not a corresponding book in books (title and author). 我想所有namebookmyBooks有没有相应的bookbooks (书名和作者)。

So, for the example, I want to retrieve: the book "Test2" because the pair ("Title 2", "Author 1") does not exist in books . 因此,对于该示例,我想要检索:书籍"Test2"因为books中不存在该对("Title 2", "Author 1")

So far, I have: 到目前为止,我有:

//myBooks/book[not(@title = //books/book/@title and @author = //books/book/@author)]

But, of course, in that case, the above XPath does not work because the combination ("Title 2", "Author 1") exists (from "book2" and "book1"). 但是,当然,在这种情况下,上述XPath不起作用,因为存在组合(“标题2”,“作者1”)(来自“book2”和“book1”)。

How can I apply the and operator on the same node? 如何在同一节点上应用and运算符?

It depends on the version of XPath. 这取决于XPath的版本。

You can't do this in a single XPath 1.0 expression because it would require a structure like 您不能在单个XPath 1.0表达式中执行此操作,因为它需要类似的结构

/bookstore/myBooks/book[/bookstore/books/book[
                  @title = _outer-predicate_/@title and
                  @author = _outer-predicate_/@author]]/@name

ie you'd need to capture the book being tested by the outer predicate so you can compare it to the inner one. 即你需要捕获外部谓词测试的书,这样你就可以将它与内部谓词进行比较。 Pure XPath 1.0 doesn't support this, you'd have to iterate over the content of myBooks yourself (eg with an xsl:for-each , as you've tagged your question "xslt"). 纯XPath 1.0不支持这一点,你必须自己迭代myBooks的内容(例如,使用xsl:for-each ,因为你已经标记了你的问题“xslt”)。

In XPath 2.0 you can do it in one expression with an explicit quantifier 在XPath 2.0中,您可以使用显式量词在一个表达式中执行此操作

/bookstore/myBooks/book[not(some $book in /bookstore/books/book satisfies
       ($book/@author = @author and $book/@title = @title))]/@name

假设XSLT我会定义一个键<xsl:key name="book" match="books/book" use="concat(@title, '|', @author)"/>然后在谓词中你可以检查[not(key('book', concat(@title, '|', @author)))]

You can concatenate attribute values using concat() and compare them: 您可以使用concat()连接属性值并进行比较:

//myBooks/book[not(concat(@*[name() = "title" or name() = "author"], ",") = concat(//books/book/@*[name() = "title" or name() = "author"], ","))]

For every book in myBook it gets the concatenation of title and author attributes and compares it with the same concatenation for every book in books . 对于每bookmyBook它得到的串联titleauthor的属性,并与每一个相同的拼接比较bookbooks

Demo (using xmllint ): 演示(使用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"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM