2

Within an AutoHotKey routine I'm using MSXML6 to parse an XML document.

doc := ComObjCreate("MSXML2.DOMDocument.6.0")
doc.setProperty("SelectionLanguage", "XPath")
doc.async := false
doc.loadXML(xmldata)
doc.selectNodes("osm/way|rel[tag[@k='railway'][@v='station']]").length

In the SelectNodes line I wish to filter the results to only two nodes: way|rel

It doesn't throw an error but ignores rel returning only way nodes.

This syntax works when using it in Saxon. Is there a solution to this in MSXML, or is there an alternative parser I could implement?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
DaveF
  • 113
  • 10

2 Answers2

3

XPath 2.0 is required to use the | within a single XPath like that. MSXML supports only XPath 1.0.

XPath 1.0

@wp78de's answer works (+1), but you can avoid having to duplicate the tag[@k='railway'][@v='station'] condition across | by using the self:: axis within the predicate :

osm/*[(self::way or self::rel) and tag[@k='railway'][@v='station']]

XPath 2.0

For the benefit of later readers who might be using a XPath 2.0 library:

osm/(way|rel)[tag[@k='railway' and @v='station']]

(@wp78de had posted this too prior to realizing that OP was limited to XPath 1.0.)

kjhughes
  • 106,133
  • 27
  • 181
  • 240
1

Since you are using MSXML (v6) you are limited to the features of XML 1.0 (as defined by the W3C as of v4). This means you are not allowed to use alternations on an axis step (ref). Therefore, you need to split your path:

doc.selectNodes("osm/way[tag[@k='railway'][@v='station']] | osm/rel[tag[@k='railway'][@v='station']]")

I've tested this end-to-end in PowerShell using MSXML6 via COM and it is working as expected.

wp78de
  • 18,207
  • 7
  • 43
  • 71