XPath select based on child value(s)
You can go with //book[./genres/genre = 'Romance']
and //book[./genres/genre = 'Romance' and ./genres/genre = 'Politics']
, respectively
All books in Romance genre:
//book[genres/genre = 'Romance']
All books in Romance and Politics genre:
//book[genres/genre = 'Romance' and genres/genre = 'Politics']
All books in Romance that are also in Politics genre (same as and
above):
//book[genres/genre = 'Romance'][genres/genre = 'Politics']
All books in Romance or Politics genre:
//book[genres/genre = 'Romance' or genres/genre = 'Politics']
All books in Romance or Politics genre (XPath 2.0 only):
//book[genres/genre = ('Romance', 'Politics')]
Notes:
//book
finds allbook
elements anywhere beneath the root element;/books/book
finds allbook
children of thebooks
root element. For the given XML, they select the same elements.- You can append
/author
to any of the above XPaths to select theauthor
elements of the books of the specified criteria.
Having trouble making it work?
First, establish that a basic XPath works: //book
should return two elements.
If it does not:
- Check spelling carefully of both the XPath expression and the XML.
- Check case. XML and XPath are case sensitive.
- Check that no namespaces are in play. Namespaces are effectively a part of the names of elements and attributes and must be accounted for. See How does XPath deal with XML namespaces?
Then, incrementally add XPath steps from there:
//book[genres]
should selectbook
elements with anygenres
child element.//book[genres/genre]
should selectbook
elements with anygenres
child element, only if it in turn has agenre
child element.//book[genres/genre = 'Romance']
should select all books in Romance genre, as requested. Note that'Romance'
must be quoted; otherwise, the expression would be testing against the string value of aRomance
child element ofbook
and will certainly fail.