hotmeatballsoup
hotmeatballsoup

Reputation: 595

Invalid XPath expression: expecting token

I have the following XML payload:

<?xml version="1.0" encoding="UTF-8" ?>
<product>
  <discount class="standard">
    <id>123</id>
    <beginDate>20181205</beginDate>
    <endDate>20181225</endDate>
  </discount>
  <account>12345</account>
</product>

The class attribute on the discount element can have the following values:

I'm trying to write an XPath expression that will match if the has a product/discount elemtn with a class of one of these values. My best attempt:

/product/discount[@class]/[@class = 'standard' or @class = 'special' or @class = 'customer' or @class = 'sale']

Produces the following error:

InvalidXPathExpression: Invalid xpath: /product/discount[@class]/[@class = 'standard' or @class = 'special' or @class = 'customer' or @class = 'sale']. Reason: javax.xml.xpath.XPathExpressionException: javax.xml.transform.TransformerException: A location step was expected following the '/' or '//' token.

Any ideas what is wrong with my XPath?

Upvotes: 0

Views: 1556

Answers (2)

Alejandro
Alejandro

Reputation: 1882

Just for fun, a shorter XPath 1.0 expression than @jsheeran excellent answer could it be:

/product/discount[@class[.='standard' or .='special' or .='customer' or .='sale']]

If class attribute is a unique token and some special character (like &#x20;) cannot be part of it, then you could use this XPath 1.0 "item IN sequence" expression:

/product
   /discount[
      contains(
         ' standard special customer sale ',
         concat(' ',@class,' ')
      )
   ]

Upvotes: 1

jsheeran
jsheeran

Reputation: 3037

As the error message indicates, / needs to be followed by a location step. Therefore, /[@class = 'standard' ...] is not a valid xPath expression.

Instead, try:

/product/discount[@class = 'standard' or @class = 'special' or @class = 'customer' or @class = 'sale']

Upvotes: 3

Related Questions