2 回答
TA贡献1851条经验 获得超4个赞
您可以使用 DOM 和 XPath 表达式。所有数据都在{https://api.nhs.uk/data/services}organisationSummary节点内。
下面的示例注册service命名空间的前缀https://api.nhs.uk/data/services(这就是s示例中的 解析为)。然后它{https://api.nhs.uk/data/services}organisationSummary使用//service:organisationSummary表达式获取任何节点。
对于每个组织,它$item使用标量值的表达式构建一个变量。循环用于{https://api.nhs.uk/data/services}addressLine节点。
// create the DOM document and load the XML
$document = new DOMDocument();
$document->loadXML($xml);
// create an Xpath instance for the document - register namespace
$xpath = new DOMXpath($document);
$xpath->registerNamespace('service', 'https://api.nhs.uk/data/services');
$json = [
"success" => true,
// force object for data - it will be an array otherwise
"data" => new stdClass()
];
// iterate over all organisationSummary nodes
foreach ($xpath->evaluate('//service:organisationSummary') as $index => $organisation) {
// fetch single values
$item = [
"name" => $xpath->evaluate('string(service:name)', $organisation),
"odscode" => $xpath->evaluate('string(service:odsCode)', $organisation),
"postcode" => $xpath->evaluate('string(service:address/service:postcode)', $organisation),
"telephone" => $xpath->evaluate('string(service:contact/service:telephone)', $organisation),
"longitude" => $xpath->evaluate('string(service:geographicCoordinates/service:longitude)', $organisation),
"latitude" => $xpath->evaluate('string(service:geographicCoordinates/service:latitude)', $organisation),
"distance" => $xpath->evaluate('string(service:Distance)', $organisation)
];
// add the addressLine values
foreach ($xpath->evaluate('service:address/service:addressLine', $organisation) as $lineIndex => $line) {
$item['addressline'.$lineIndex] = $line->textContent;
}
// add the $item
$json['data']->{$index} = $item;
}
echo json_encode($json, JSON_PRETTY_PRINT);
输出:
{
"success": true,
"data": {
"0": {
"name": "Highfields Surgery (R Wadhwa)",
"odscode": "C82116",
"postcode": "LE2 0NN",
"telephone": "01162543253",
"longitude": "-1.11859357357025",
"latitude": "52.6293983459473",
"distance": "0.247038430918239",
"addressline0": "25 Severn Street",
"addressline1": "Leicester",
"addressline2": "Leicestershire"
},
"1": {
"name": "Dr R Kapur & Partners",
"odscode": "C82659",
"postcode": "LE2 0TA",
"telephone": "01162951258",
"longitude": "-1.11907768249512",
"latitude": "52.6310386657715",
"distance": "0.30219913005026",
"addressline0": "St Peters Health Centre",
"addressline1": "Sparkenhoe Street",
"addressline2": "Leicester",
"addressline3": "Leicestershire"
},
...
TA贡献1877条经验 获得超1个赞
您需要使用适当的方法来遍历 XML 文档,而不是查看每个元素并检查其名称。
您的两个最佳选择是 DOM 方法和 XPath。如果您使用过前端 JavaScript 代码(例如document.getElementsByTagName或document.getElementById),您就会熟悉前者。后者具有更陡峭的学习曲线,但功能要强大得多。(XSLT 也是转换 XML 的好选择,但我对它不是很熟悉。)
不过,第一步是使用正确的 XML 库。您使用的 XML 函数级别非常低。我建议改用 PHP 的DomDocument扩展。让我们潜入吧!
<?php
$xml = file_get_contents("nhs.xml");
// assume XML document is stored in a variable called $xml
$dom = new DomDocument;
$dom->loadXml($xml);
// thankfully we can ignore namespaces!
$summaries = $dom->getElementsByTagName("organisationSummary");
// go through each <organisationSummary> element
foreach ($summaries as $os) {
$entry_data = [
// note we're using $os and not $dom now, so we get child elements of this particular element
"name" => $os->getElementsByTagName("name")[0]->textContent,
"odscode" => $os->getElementsByTagName("odsCode")[0]->textContent,
"addressline0" => $os->getElementsByTagName("addressLine")[0]->textContent,
// provide a default empty string in case there's no further lines
"addressline1" => $os->getElementsByTagName("addressLine")[1]->textContent ?? "",
"addressline2" => $os->getElementsByTagName("addressLine")[2]->textContent ?? "",
"addressline3" => $os->getElementsByTagName("addressLine")[3]->textContent ?? "",
"postcode" => $os->getElementsByTagName("postcode")[0]->textContent,
"telephone" => $os->getElementsByTagName("telephone")[0]->textContent,
"longitude" => $os->getElementsByTagName("longitude")[0]->textContent,
"latitude" => $os->getElementsByTagName("latitude")[0]->textContent,
"distance" => $os->getElementsByTagName("Distance")[0]->textContent,
];
$json_data[] = $entry_data;
}
if (count($json_data)) {
$output = ["success" => true, "data" => $json_data];
} else {
$output = ["success" => false];
}
echo json_encode($output, JSON_PRETTY_PRINT);
- 2 回答
- 0 关注
- 166 浏览
添加回答
举报