Reputation: 47
I'm having a problem formating an xpath query. I'm trying to get products that have a serviceTechnology = 'DSL'.
I've tried:
//offering/productDefinition[definitionID='Product_1' or
definitionID='Product_2' or
definitionID='Product_3' or
definitionID='Product_4'
and serviceTechnologyList[serviceTechnology='DSL']]
//offering/productDefinition[definitionID='Product_1' or
definitionID='Product_2' or
definitionID='Product_3' or
definitionID='Product_4'
and serviceTechnologyList='DSL']
This was based on other questions list here. I keep getting "Predicate Format Error".
<offeringList>
<offering>
<productDefinition>
<definitionID>Product_1</definitionID>
<productLineList>
<productLine>DSL</productLine>
</productLineList>
<serviceTechnologyList>
<serviceTechnology>DSL</serviceTechnology>
</serviceTechnologyList>
</productDefinition>
</offering>
<offering>
<productDefinition>
<definitionID>Product_2</definitionID>
<productLineList>
<productLine>DSL</productLine>
</productLineList>
<serviceTechnologyList>
<serviceTechnology>IPTV</serviceTechnology>
</serviceTechnologyList>
</productDefinition>
</offering>
<offering>
<productDefinition>
<definitionID>Product_3</definitionID>
<productLineList>
<productLine>DSL</productLine>
</productLineList>
<serviceTechnologyList>
<serviceTechnology>DSL</serviceTechnology>
</serviceTechnologyList>
</productDefinition>
</offering>
<offering>
<productDefinition>
<definitionID>Product_4</definitionID>
<productLineList>
<productLine>DSL</productLine>
</productLineList>
</productDefinition>
</offering>
</offeringList>
Any help would be appreciated.
Upvotes: 0
Views: 171
Reputation:
As @icyrock.com points out, the problem is in boolean operators: and
has more precedence than or
.
This expression use another approach for matching against a sequence in XPath 1.0:
//offering/productDefinition
[contains('|Product_1|Product_2|Product_3|Product_4|',
concat('|',definitionID,'|'))
and serviceTechnologyList/serviceTechnology='DSL']
If the list of ID gets too big, you could use:
//offering/productDefinition
[starts-with(definitionID,'Product_')
and contains('|1|2|3|4|6|8|22|',
concat('|',
substring-after(definitionID,
'Product_'),
'|'))
and serviceTechnologyList/serviceTechnology='DSL']
Or if there is a range:
//offering/productDefinition
[starts-with(definitionID,'Product_')
and substring-after(definitionID,'Product_') >= 1
and 4 >= substring-after(definitionID,'Product_')
and serviceTechnologyList/serviceTechnology='DSL']
Upvotes: 0
Reputation: 28618
You need parentheses to define the priority of and
and or
operators:
//offering/productDefinition[(definitionID='Product_1' or definitionID='Product_2' or definitionID='Product_3' or definitionID='Product_4') and serviceTechnologyList[serviceTechnology='DSL']]
If you just want productDefinition
nodes that have serviceTechnology='DSL'
, you can simplify to something like:
//productDefinition[serviceTechnologyList[serviceTechnology='DSL']]
Upvotes: 0
Reputation: 384
Why not just:
/offeringList/offering/productDefinition[serviceTechnologyList/serviceTechnology = 'DSL']
Or you can do the following if you want to be specific about definitionIDs:
//offeringList/offering/productDefinition[serviceTechnologyList/serviceTechnology = 'DSL'][definitionID='Product_1' or definitionID='Product_2' or definitionID='Product_3' or definitionID='Product_4']
Upvotes: 0
Reputation: 144
I see no errors at glance - both work:), maybe you are not escaping something ?
Try your queries here to see that work ok: xpath tester
Upvotes: 1