D. Caan
D. Caan

Reputation: 2019

XPath replace FOR statement

I have this XPath (Thanks to Ian Roberts' answer in SO Xpath2.0 selecting first and last occurance of string with iteration) :

Events/Properties[
  count(
    for $me in (Property[@Descriptor="200"]) return
      (preceding-sibling::Properties[1][Property[@Descriptor="200"] = $me],
       following-sibling::Properties[1][Property[@Descriptor="200"] = $me])
  ) != 2
]

The XPath is great but the tool I'm using is not accepting for statement.

How could I rewrite this XPath to avoid this issue [without for statement]?

Upvotes: 0

Views: 71

Answers (1)

Tomalak
Tomalak

Reputation: 338336

Assuming that your input is ordered (that's the important bit!), you can do it by issuing these XPath 1.0 expressions:

First ones in group:

//Properties[
  Property/@Descriptor = 200
  and not(
    Property = preceding-sibling::*/Property[@Descriptor = 200]
  )
]

last ones in group:

//Properties[
  Property/@Descriptor = 200
  and not(
    Property = following-sibling::*/Property[@Descriptor = 200]
  )
]

You can go from there and select Property[@Descriptor = 100] or Property[@Descriptor = 200] individually.


You can combine both expressions into one:

//Properties[
  Property/@Descriptor = 200 and ( 
    not(
      Property = preceding-sibling::*/Property[@Descriptor = 200]
    ) or not(
      Property = following-sibling::*/Property[@Descriptor = 200]
    ) 
  )
]

You would get a list of <Properties> pairs (first and last ones in their respective groups), except for groups that are one element long. That means there's no guarantee that you would not get an even number of nodes returned.

Upvotes: 1

Related Questions