-1

Possible Duplicate:
Parse XML with Namespace using SimpleXML

I'm new to xpath, and unable to get this to parse. It produces no output.

This contains XML returned from Google Map API V3. I want to have it parse and return the Zip Code from the PostalCode/PostalCodeNumber. I set-up this test because I need to be able to make sure I can get to the PostalCode/PostalCodeNumber even if Google's API puts other tags in the way, which is does sometimes. So it's important for me to get the xpath working because I want to be able to get direct access to things like PostalCode/PostalCodeNumber without relying on static tree structure path. Please be kind and helpful on your reply, thanks!

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>40.74445606,-73.97495072</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">
    <address>317 E 34th St, New York, NY 10016, USA</address>
    <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>NY</AdministrativeAreaName><Locality><LocalityName>New York</LocalityName><Thoroughfare><ThoroughfareName>317 E 34th St</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>10016</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="40.7458050" south="40.7431070" east="-73.9736017" west="-73.9762997" />
    </ExtendedData>
    <Point><coordinates>-73.9749507,40.7444560,0</coordinates></Point>
  </Placemark>
</Response></kml>
XML;

$xml = new SimpleXMLElement($xml);

$result = $xml->xpath('PostalCode/PostalCodeNumber');

while(list( , $node) = each($result)) {
    echo 'PostalCode/PostalCodeNumber: ',$node,"\n";
}
?>
Community
  • 1
  • 1
Edward
  • 9,430
  • 19
  • 48
  • 71
  • 1
    My first impulse is to suspect that your ?> is killing your String... have you verified that you have a valid XML there? – Yevgeny Simkin Oct 16 '12 at 22:44
  • Yes, I have done a var_dump($xml) and it looks fine. You can insert a var_dump($xml); in there and see. – Edward Oct 16 '12 at 22:47
  • I could really use help with the right syntax here, that other posting doesn't address the method I'm having a problem with. Thanks! – Edward Oct 16 '12 at 22:53
  • 1
    @Edward: The comments are already there, and the chances of his removing them are pretty slim. :) Flag them if you feel they're offensive. But the content of them appears to be essentially correct. XML cares about namespaces -- this document's `(urn:oasis:names:tc:ciq:xsdschema:xAL:2.0)PostalCode` and your `PostalCode`, for example, don't match. You need to specify a namespace, and the highest-voted answer to the other question covers how to do that. – cHao Oct 16 '12 at 23:19
  • You *could*, of course, get the data in JSON format instead, then it would be easier to extract the data that you need. – uınbɐɥs Oct 16 '12 at 23:28
  • Thanks for your reply. The example I was using for xpath was from php.net, but it didn't work with my XML. Choroba's posting below was very helpful. As for the jerk's comments, I don't care if he removes them, he has to live with himself we don't. :-) – Edward Oct 16 '12 at 23:28
  • @Edward: Here is another xpath example from php.net that covers the issue you have: http://www.php.net/manual/en/simplexmlelement.registerxpathnamespace.php – hakre Oct 16 '12 at 23:29
  • Shaquin, You raise a good point, but I was trying to do this with XML because XML keeps coming up all the time under different situations, so it was time to solve this kind of problem which Choroba provided below. – Edward Oct 16 '12 at 23:29

2 Answers2

2

Postal code lies in a namespace. You have to specify the namespace in the XPath expression to match the element:

$xml = new SimpleXMLElement($xml);
$xml->registerXPathNamespace('urn', 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0');
$result = $xml->xpath('//urn:PostalCodeNumber');
choroba
  • 231,213
  • 25
  • 204
  • 289
  • This worked out perfectly! The best way to learn is have a working example, so I think you for your kind help! – Edward Oct 16 '12 at 23:20
  • @Edward: If you want to learn by examples, I suggest you take a look in the manual: http://www.php.net/manual/en/simplexmlelement.registerxpathnamespace.php – hakre Oct 16 '12 at 23:28
0

Use descendant::PostalCode or //PostalCode.

Note that in the above links I removed the namespace definitions from your xml for it to work. Look at http://www.edankert.com/defaultnamespaces.html#Conclusion for a clear explanation.

See W3Schools for an easy to understand XPath introduction.

Developer
  • 231
  • 4
  • 19
Alin Mircea
  • 169
  • 1
  • 7