With XPath, I know that you can use the union operator in the following way:
//*[@id="Catalog"]/thead | //*[@id="Catalog"]/tbody
This seems to be a little awkward to me though. Is there a way to do something similar to one of these instead?
//*[@id="Catalog"]/(thead|tbody)
//*[@id="Catalog"]/(thead or tbody)
//*[@id="Catalog"]/*[nodename="thead" or nodename="tbody"]
That seems a lot more readable and intuitive to me...
While the expression:
//*[@id="Catalog"]/*[name()="thead" or name()="tbody"]
is correct
This expression is more efficient:
//*[@id="Catalog"]/*[self::thead or self::tbody]
There is yet a third way to check if the name of an element is one of a specified sequence of strings:
//*[@id="Catalog"]/*[contains('|thead|tbody|',concat('|',name(),'|'))]
Using this last technique can be especially practical in case the number of possible names is very long (of unlimited and unknown length). The pipe-delimited string of possible names can even be passed as an external parameter to the transformation, which greatly increases its generality, re-usability and "DRY"-ness.
Note that with XPath 2.0 your attempt //*[@id="Catalog"]/(thead|tbody)
is correct. That approach does not work however with XPath 1.0.
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