Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

xml

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> 
like image 916
topless Avatar asked Apr 14 '11 11:04

topless


People also ask

How do you find an element with multiple classes?

Use the getElementsByClassName method to get elements by multiple class names, e.g. document. getElementsByClassName('box green') . The method returns an array-like object containing all the elements that have all of the given class names.

Can you have multiple classes on an element?

HTML elements can be assigned multiple classes by listing the classes in the class attribute, with a blank space to separate them.

Can I use class in XPath?

Xpath class is defined as a selector that is usually shared by multiple elements in the document means it extracts all the class names. Nodes or lists of nodes are selected using XPath expressions based on property class names. The class name is separated by a Spaces. This token has white space.

Can class selector have multiple classes?

class selector can also be used to select multiple classes.


2 Answers

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 '))] 
like image 81
Mads Hansen Avatar answered Sep 21 '22 06:09

Mads Hansen


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 
like image 42
Dennis Münkle Avatar answered Sep 21 '22 06:09

Dennis Münkle