Reputation: 911
I have this XML:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<site>
<id>123</id>
<po>BT123</po>
</site>
<order>
<shipping>
<shippingmethod>1</shippingmethod>
<firstname>Test</firstname>
<lastname>User</lastname>
<address>1234 My Place</address>
<address2>Apt 101</address2>
<city>Anytown</city>
<state>AL</state>
<zip>12345</zip>
</shipping>
<orderitems>
<item>
<isbn>9780752419930</isbn>
<rentalterm>1</rentalterm>
</item>
<item>
<isbn>0495599336</isbn>
<rentalterm>3</rentalterm>
</item>
<item>
<isbn>0743500210</isbn>
<rentalterm>2</rentalterm>
</item>
</orderitems>
</order>
</xml>
What I want to do is get all the ISBNs where the rental term is not 2 I know how to get ALL the ISBNs:
//item/isbn/text()
and specific rental terms:
//item[rentalterm!=2]
But I am not sure how to put them together. Any suggestions?
Upvotes: 1
Views: 82
Reputation: 60414
Use this expression:
//item[not(rentalterm='2')]/isbn/text()
In English: Get the text nodes of any isbn
element the parent of which is an item
element not having a rentalterm
child whose value is equal to 2
Contrast with this expression:
//item[rentalterm!=2]/isbn/text()
...which translates to: Get the text nodes of any isbn
element the parent of which is an item
element having at least one rentalterm
child whose value is not equal to 2
.
In other words, this second expression will not match item
elements that have no rentalterm
children, but will match item
elements with multiple rentalterm
children as long as at least one does not have a string value equal to 2
.
To put it yet another way, the predicate [not(rentalterm='2')]
can be read as does not contain a rentalterm
child whose string value is equal to 2
, whereas [rentalterm!=2]
should be read as contains a rentalchild
whose string value is not equal to 2
.
The spec describes it like this:
If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true.
Upvotes: 3
Reputation: 9048
Just use:
//item[rentalterm!=2]/isbn/text()
assuming all items have a rentalterm child.
Upvotes: 1