tags:

views:

41

answers:

2

Hi, I'm looking to select a collection of elements based on an array of ID names. I'm currently using a giant OR statement essentially:

//*[@id='apple']|//*[@id='orange']|//*[@id='banana']

But building that string manually seems messy. Is there something like a nice SQL-esque "WHERE IN [a,b,c]" operator that I could be using?

I am using the HTTPAgilityPack for ASP.Net which I think equates to XPath1.o (feel free to correct me on that.)

Thanks.

+3  A: 

First, you could simplify this by using or. This avoids repeating the //* multiple times although you till specify the @id= part multiple times:

//*[@id='apple' or @id='orange' or @id='banana']

A more elegant solution is to check against a list of acceptable ids. Now if you're using XPath 1.x then you'll have to do a bit of gymnastics to get contains() to do your bidding. Specifically, notice that I've got spaces on both ends of the first string, and then concatenate spaces to each end of @id before looking for a match. This is to prevent an @id of "range" from matching, for example.

//*[contains(' apple orange banana ', concat(' ', @id, ' '))]

If you have are using XPath 2.0 then the way forward is simpler thanks to the addition of sequences to the language:

//*[exists(index-of(('apple', 'orange', 'banana'), @id))]
John Kugelman
+3  A: 

Use:

//*[contains('|apple|banana|orange|', concat('|',@id, '|'))]

In case some of the id attributes may contain the "|" character, use another instead, that is known not to be present in the value of any of the id attributes.

An XPath 2.0 solution:

//*[@id=('apple', 'orange', 'banana')]

Dimitre Novatchev
@Dimitre: +1 for better XPath 2.0 expresion.
Alejandro
I wasn't able to test the 2.0 expressions. Gave a +1 though!
LesterDove