DOM XPath query help

so this xpath request is driving me crazy. I am trying to search for an xml file (in this case an kml file for use with google maps api) of golf courses for a specific type of course and grab each corresponding <Placemark> element so that I can create a new xml with the results so that I can further filter the new inquiry. The problem is that I cannot figure out how to get each corresponding <Placemark> element

 $xml = '<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.1"> <Document> <Placemark id="placemark3"> <name>Test Country Club</name> <description> <![CDATA[ <div class="contact">Post Office Box 329 <a href="#" target="_blank">website</a></div> ]]> </description> <alpha>a</alpha> <position>2</position> <type>Public/Daily Fee</type> <styleUrl>#nineholeStyle</styleUrl> <Point> <coordinates>-79.285576,37.111809</coordinates> </Point> </Placemark> </Document> </kml>'; $dom = new DOMDocument(); $dom->loadXML($xml); $xpath = new DOMXPath($dom); //trying to get any Placemark element where type child matches a specific query //in this case we want to search for Public/Daily Fee and return the placemark and everything inside it. $query = $xpath->query("//Placemark[type='Public/Daily Fee']/ancestor::Placemark");; foreach ($query as $result) { //eventually want to merge each result into new xml object to be further filtered } 

Any help would be greatly appreciated. Thanks

+3
dom php xpath
source share
1 answer

You have not registered an XML namespace before the request.

 // register it $xpath->registerNamespace('kml', "http://earth.google.com/kml/2.1"); // and use it, too ! $query = $xpath->query("//kml:Placemark[kml:type='Public/Daily Fee']"); 

( ancestor::kml:Placemark in your expression does not make sense, I left it.)

The namespace prefix in the XPath query should be used even if the namespace in question is the default namespace of the XML document (for example, in your case).

The element <kml xmlns="http://earth.google.com/kml/2.1"> equivalent to <kml:kml xmlns:kml="http://earth.google.com/kml/2.1" >.

However, the XPath /kml query is not equivalent to /kml:kml . The latter will correspond to both elements (when the kml namespace is registered in advance), the former will not match any of them, no matter what you do.

Also note that you do not need to use the same namespace prefix that is used in the XML document.

Assume an XML document:

 <kml:kml xmlns:kml="http://earth.google.com/kml/2.1"> <kml:Document /> </kml:kml> 

Then you can still do this:

 $xpath->registerNamespace('foo', "http://earth.google.com/kml/2.1"); $query = $xpath->query("/foo:kml/foo:Document"); 

and return the correct result. Namespace prefixes are simply shorthand.

+8
source share

All Articles