Search code examples
xmlxpathkmlxmlstarlet

Why does this XPath expression not return the correct value in xmlstarlet?


I'm trying to extract the contents of the 'coordinates' node in this KML file using xmlstarlet.

The KML file validates fine using xmlstarlet itself.

I've whittled it down to a small test file containing:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<Placemark>
    <name>eurovelo-5 690</name>
    <Snippet></Snippet>
    <description><![CDATA[&nbsp;]]></description>
    <styleUrl>#style390</styleUrl>
    <LineString>
      <tessellate>1</tessellate>
      <coordinates>
        10.146948,44.790592,97.500000
        10.146958,44.790562,97.599998
        10.147018,44.790497,97.699997
        10.147083,44.790466,97.699997
      </coordinates>
    </LineString>
  </Placemark>
  </Document>
</kml>

Running this query fails though:

xmlstarlet sel -t -c "//coordinates/text()" test.kml

This appears to parse correctly using the online path tool - http://www.qutoric.com/xslt/analyser/xpathtool.html

Am I missing something here?


Solution

  • You need to define and use a namespace prefix for http://earth.google.com/kml/2.2 test.kml - something like this:

    xmlstarlet sel -t -c "//kml:coordinates/text()" -N kml=http://earth.google.com/kml/2.2 test.kml
    

    XPaths do not have a default namespace - if a name in a XPath does not specify a namespace prefix it is assumed to be in the null namespace; hence it is necessary to always specify a namespace prefix when trying to match nodes whose names are in a namespace different from the null one (as in this case).