2011-08-22 94 views
4

我一直在嘗試使用PHP中的XPath來訪問National Health Service API中的Atom提要。使用XPath通過命名空間進行選擇

的數據是這樣的:

<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是空的,但它應該有10個條目。

請有人解釋一個好方法來打印出每個<s:addressLine>節點的內容,並將郵政編碼放入一個var。

我在實踐中使用命名空間原則,雖然這對我來說是相當新的。感謝您提供的關於學習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 '}'; 
} 

?> 
+1

除非你不確定的XML是否會保留其命名空間,有沒有特別需要註冊。 '$ sxml-> xpath('// s:address');'仍然有效。雖然不能真正傷害。 –

+0

刪除了關於內部服務器錯誤的第一條評論。這可能是由於缺少apikey。 ;-)當我複製你的示例XML時,它工作正常。 –

回答

5

這個工作對我來說:

$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 
+0

這實際上打印每個地址n(10)次。我只是使用array_pop來獲取':address' SimpleXML對象。謝謝,但真的有幫助:) – Alex

+0

@ alexw你能解釋一下你如何使用array_pop? –

2

以前的答案幫了我很多!所以這裏去完整的解決方案。

$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... 
+0

嗨NomikOS ...我也做了更新,請看看,欣賞評論...在那順便好工作。 :) – Alex

+0

@alexw啊!是。你最後的編輯看起來很棒。我會考慮它。謝謝! –

+0

謝謝!讚賞。 – Alex