Using XPath to select through namespaces

I am trying to use XPath in PHP to access an Atom feed from the National Health Service API.

The data is as follows:

<feed xmlns:s="http://syndication.nhschoices.nhs.uk/services" xmlns="http://www.w3.org/2005/Atom"> <title type="text">NHS Choices - GP Practices Near Postcode - W1T4LB - Within 5km</title> <entry> <id>http://v1.syndication.nhschoices.nhs.uk/organisations/gppractices/27369</id> <title type="text">Fitzrovia Medical Centre</title> <updated>2011-08-20T22:47:39Z</updated> <link rel="self" title="Fitzrovia Medical Centre" href="http://v1.syndication.nhschoices.nhs.uk/organisations/gppractices/27369?apikey="/> <link rel="alternate" title="Fitzrovia Medical Centre" href="http://www.nhs.uk/ServiceDirectories/Pages/GP.aspx?pid=303A92EF-EC8D-496B-B9CD-E6D836D13BA2"/> <content type="application/xml"> <s:organisationSummary> <s:name>Fitzrovia Medical Centre</s:name> <s:address> <s:addressLine>31 Fitzroy Square</s:addressLine> <s:addressLine>London</s:addressLine> <s:postcode>W1T6EU</s:postcode> </s:address> <s:contact type="General"> <s:telephone>020 7387 5798</s:telephone> </s:contact> <s:geographicCoordinates> <s:northing>182000</s:northing> <s:easting>529000</s:easting> <s:longitude>-0.140267259415255</s:longitude> <s:latitude>51.5224357586293</s:latitude> </s:geographicCoordinates> <s:Distance>0.360555127546399</s:Distance> </s:organisationSummary> </content> </entry> </feed> 

Now I use this code to access node.

 <?php $feedURL = 'http://v1.syndication.nhschoices.nhs.uk/organisations/pharmacies/postcode/W1T4LB.xml?apikey=&range=5'; $xml = file_get_contents($feedURL); $sxml = new SimpleXMLElement($xml); $sxml->registerXPathNamespace('a', 'http://www.w3.org/2005/Atom'); $sxml->registerXPathNamespace('s', 'http://syndication.nhschoices.nhs.uk/services'); $addr = $sxml->xpath('//s:address'); var_dump($addr[0]); ?> 

Here $addr empty, but should have ten entries.

Please can someone explain a good way to print the contents of the <s:addressLine> node and put the zip code in var.

I work with the namespace principle in practice, although this is completely new to me. Evaluate any information you could share about learning XPath and the PHP SimpleXML model.

Rate the help.

EDIT -

After seeing the update below, I decided to include my final output code in it:

 function doPharmacy($postcode, $request, $prev, $next) { $feedURL = 'http://v1.syndication.nhschoices.nhs.uk/organisations/pharmacies/postcode/' . $postcode . '.xml?apikey=&range=5'; $xml = file_get_contents($feedURL); $sxml = new SimpleXMLElement($xml); $sxml->registerXPathNamespace('a', 'http://www.w3.org/2005/Atom'); $sxml->registerXPathNamespace('s', 'http://syndication.nhschoices.nhs.uk/services'); ////////////// XPATH \\\\\\\\\\\\\\ $addrLines = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:content/s:organisationSummary/s:address/s:addressLine'); $nhsPostcode = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:content/s:organisationSummary/s:address/s:postcode'); $tel = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:content/s:organisationSummary/s:contact/s:telephone'); $distance = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:content/s:organisationSummary/s:Distance'); $title = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:title'); $link = $sxml->xpath('/a:feed/a:entry[' . $request . ']/a:link[@rel="alternate"]/@href'); $nhsPostcode = array_pop($nhsPostcode); // always taking first node from set $tel = array_pop($tel); $distance = (double)array_pop($distance); $title = array_pop($title); $link = array_pop($link); ////////////// OUTPUT: JSON \\\\\\\\\\\\\\ print '{"addr": "'; foreach ($addrLines as $addr) { print $addr . '<br />'; // ok to use HTML tags in JSON } print '",'; print '"postcode": "' . $nhsPostcode . '",'; print '"tel": "' . $tel . '",'; $num = number_format($distance, 2); print '"distance": "' . $num . '",'; print '"title": "' . $title . '",'; print '"link": "' . $link . '",'; $nhsPostcode = urlencode($nhsPostcode); print'"mapsURL": "http://maps.googleapis.com/maps/api/staticmap?center=' . $nhsPostcode . '&zoom=15&size=155x137&sensor=false&scale=2",'; print '"prev": "' . $prev . '",'; print '"next": "' . $next . '"'; print '}'; } ?> 
+4
source share
2 answers

This works for me:

 $addr = $sxml->xpath('//s:address'); foreach ($addr as $a) { $addressLine = $a->xpath('s:addressLine'); foreach ($addressLine as $al) { echo (string)$al."<br/>"; } $postalCode = $a->xpath('s:postcode'); foreach ($postalCode as $p) { echo (string)$p."<br/>"; } } 

What is displayed:

 31 Fitzroy Square London W1T6EU 
+6
source

The previous answers helped me a lot! So, let's get to the full solution.

  $feedURL = "http://v1.syndication.nhschoices.nhs.uk/organisations/pharmacies/postcode/{$user->postcode}.xml?apikey=XXXX&range=100"; $xml = simplexml_load_file($feedURL); $xml->registerXPathNamespace('s', 'http://syndication.nhschoices.nhs.uk/services'); $org = $xml->xpath('//s:organisationSummary'); $i = 0; $item = array(); foreach ($org as $o) { $aux = $o->xpath('s:name'); $item[$i]['name'] = (string) $aux[0]; $addr = $o->xpath('s:address'); foreach ($addr as $a) { $aux = ''; $addressLine = $a->xpath('s:addressLine'); foreach ($addressLine as $a2) { $aux .= (string) $a2[0] . "\n"; } $aux2 = $a->xpath('s:postcode'); if (is_array($aux2)) { $aux .= (string) $aux2[0]; } $item[$i]['address'] = $aux; } $i ++; } 

This will provide:

 array ( 0 => array ( 'name' => 'Your Local Boots Pharmacy', 'address' => 'Century House Station Road Manningtree CO11 1AA', ), 1 => array ( 'name' => 'The Pharmacy', 'address' => 'The Street East Bergholt CO7 6SE', ), and so on... 
+2
source

All Articles