【发布时间】:2011-08-22 16:04:47
【问题描述】:
我一直在尝试使用 PHP 中的 XPath 从 National Health Service API 访问 Atom 提要。
数据如下:
<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> 节点内容并将邮政编码放入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 '}';
}
?>
【问题讨论】:
-
除非您不确定 XML 是否会保留其名称空间,否则没有特别需要注册它们。
$sxml->xpath('//s:address');仍然有效。不过不会真的受伤。 -
删除了关于内部服务器错误的第一条评论。这可能是由于缺少 apikey。 ;-) 当我复制您的示例 XML 时,它可以正常工作。
-
官方php文档给出了如何处理命名空间php.net/manual/en/simplexmlelement.registerxpathnamespace.php的例子