CroweMan
CroweMan

Reputation:

XPATH Multiple Element Filters

I have the following sample XML structure:

<SavingAccounts>
    <SavingAccount>
       <ServiceOnline>yes</ServiceOnline>
       <ServiceViaPhone>no</ServiceViaPhone>
    </SavingAccount>
    <SavingAccount>
       <ServiceOnline>no</ServiceOnline>
       <ServiceViaPhone>yes</ServiceViaPhone>
    </SavingAccount>
</SavingAccounts>

What I need to do is filter the 'SavingAccount' nodes using XPATH where the value of 'ServiceOnline' is 'yes' or the value of 'ServiceViaPhone' is yes.

The XPATH should return me two rows!! I can filter 'SavingAccount' nodes where both of the element values are yes like the following XPATH sample, but what I want to do is an or element value comparison???

/SavingAccounts/SavingAccount/ServiceOnline[text()='yes']/../ServiceViaPhone[text()='yes']/..

Upvotes: 24

Views: 76547

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243539

This is a very fundamental XPath feature: composing a number of conditions with the logical operators and, or, and the function not().

and has a higher priority than or and both operators have lower priority than the relational and equality operators (=, !=, >, >=, &lt; and &lt;=).

So, it is safe to write: A = B and C = D

Some most frequent mistakes made:

  1. People write AND and/or OR. Remember, XPath is case-sensitive.

  2. People use the | (union) operator instead of or

Lastly, here is my solution:

/SavingAccounts/SavingAccount
           [ServiceOnLine='yes' or ServiceViaPhone='yes']

Upvotes: 66

falstro
falstro

Reputation: 35667

Will

/SavingAccounts/SavingAccount[ServiceOnline/text()='yes' or ServiceViaPhone/text()='yes']

do the trick?

I have no XPath evaluator handy at the moment.

EDIT:
If I remember correctly, you don't need the text(), so

[ServiceOnline='yes' or ServiceViaPhone='yes']

should be sufficient, and more readable.

EDIT:
Yes, of course, 'or' for predicate expressions, my bad.

Upvotes: 4

AnthonyWJones
AnthonyWJones

Reputation: 189505

/SavingAccounts/SavingAccount[(ServiceOnLine='yes') or (ServiceViaPhone='yes')]

Upvotes: 10

Related Questions