This works:
(//someparentpath/h3 | //someparentpath/ul/li/div)/somechildpath
This does not :( Why?
//someparentpath/(h3 | ul/li/div)/somechildpath
Good question, I'm interested in the "why" myself.
As a practical matter, though, you can rewrite this
//someparentpath/(h3 | ul/li/div)/somechildpath
as this (not quite equivalent)
//someparentpath//*[self::h3 or self::ul/li/div]/somechildpath
Which is not too much worse.
But yeah, I've been frustrated by that.
XPath 1.0's grammar does not allow alternations in axis steps, see the specifications for node sets or try the XPath 1.0 Grammar Test Page. Your first query is allowed by the grammar, the second is no valid XPath 1.0.
If you've got any chance, switch to an XPath 2.0 implementation which offers much more possibilities in querying XML. Both of your queries are valid XPath 2.0 statements.
In XPath 1.0, you will have to either:
Completely write out the path two times and use the union of those:
//someparentpath/h3/somechildpath | //someparentpath/ul/li/div/somechildpath
or the allowed query with common axis steps in the end, which is at least a little bit less repeating:
(//someparentpath/h3 | //someparentpath/ul/li/div)/somechildpath
Use some descending-or-self
-hack with predicates like proposed by harpo and JLRishe, but they have both in common that you might match more elements than you want to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With