Использование XPath для выбора через пространства имен - PullRequest
6 голосов
/ 22 августа 2011

Я пытался использовать XPath в PHP для доступа к каналу Atom из API Национальной службы здравоохранения.

Данные выглядят так:

<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>

Я сейчасиспользование этого кода для доступа к узлу.

<?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]);

?>

Здесь $addr пусто, но в нем должно быть десять записей.

Пожалуйста, кто-нибудь может объяснить хороший способ распечатать каждый <s:addressLine>содержимое узла и размещение почтового индекса в переменной.

На практике я работаю с принципом пространства имен, хотя для меня это довольно ново.Цените любую информацию, которую вы можете передать об изучении XPath и модели PHP SimpleXML.

Цените помощь.

РЕДАКТИРОВАТЬ -

Видя обновление, приведенное ниже, я решил поставитьмой окончательный код вывода в это:

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 '}';
}

?>

Ответы [ 2 ]

8 голосов
/ 22 августа 2011

Это работает для меня:

$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/>";
    }
}

Который отображает:

31 Fitzroy Square
London
W1T6EU
2 голосов
/ 08 октября 2011

Предыдущие ответы мне очень помогли!Итак, вот полное решение.

    $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 ++;
    }

Это обеспечит:

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...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...