开发者

How can I select an element with multiple classes with Xpath?

In the above xml sample I would like to select all the books that belong to class foo and not in class bar by using xpath.

<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
  <book class="foo">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book class="foo bar">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book class="foo bar">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <开发者_开发技巧;year>2005</year>
    <price>29.99</price>
  </book>
</bookstore>


By padding the @class value with leading and trailing spaces, you can test for the presence of " foo " and " bar " and not worry about whether it was first, middle, or last, and any false positive hits on "food" or "barren" @class values:

/bookstore/book[contains(concat(' ',@class,' '),' foo ')
        and not(contains(concat(' ',@class,' '),' bar '))]


Although I like Mads solution: Here is another approach for XPath 2.0:

/bookstore/book[
                 tokenize(@class," ")="foo" 
                 and not(tokenize(@class," ")="bar")
               ]

Please note that the following expressions are both true:

("foo","bar")="foo" -> true
("foo","bar")="bar" -> true


XPath 2.0:

/*/*[for $s in concat(' ',@class,' ') 
            return 
               matches($s, ' foo ') 
             and 
              not(matches($s, ' bar '))
      ]

Here no tokenization is done and $s is calculated only once.

Or even:

/*/book[@class
          [every $t in tokenize(.,' ') satisfies $t ne 'bar']
          [some  $t in tokenize(.,' ') satisfies $t eq 'foo']
       ]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜