XPath - Selecting preceding and following sibling of a specific node in a single query
python, xml, xpath
Solution
If you are using lxml (which currently only supports XPath version 1.0), you have to spell out each XPath entirely, and join them with `|`:
'''/osm/way/nd[@ref=203936110]/following-sibling::nd[1]
| /osm/way/nd[@ref=203936110]/preceding-sibling::nd[1]'''
For example,
import lxml.etree as ET
content = '''\
<record>
<nd>First</nd>
<nd>Second</nd>
<nd ref="203936110"></nd>
<nd>Third</nd>
<nd>Fourth</nd>
</record>'''
root = ET.fromstring(content)
for elt in root.xpath('''
//nd[@ref="203936110"]/following-sibling::nd[1]
|
//nd[@ref="203936110"]/preceding-sibling::nd[1]'''):
print(elt.text)
yields
Second
Third
Problem
I'm currently working with Open Street Maps data and I'm trying to select the preceding and following sibling of a specific node. My queries currently look like this : ``` /osm/way/nd[@ref=203936110]/following-sibling::nd[1] /osm/way/nd[@ref=203936110]/preceding-sibling::nd[1] ``` These queries work as expected but I'd like to merge them into a single query. I did found some examples mentioning that this is possible but for some reason I haven't been able to find the right syntax to make it work. This query, for example, is invalid : ``` /osm/way/nd[@ref=203936110]/(following-sibling::nd[1] or preceding-sibling::nd[1]) ```