如何为此 XML 正确编写 DOMXPath 查询?
How to correctly write a DOMXPath query for this XML?
我正在编写一个脚本来解析 this XML。
我想用 DOMDocument and DOMXpath 解析所有 <Contents>
节点。但是由于某种原因,我尝试的所有 XPath 查询都失败了。
我的代码:
<?php
$apiUrl = 'https://chromedriver.storage.googleapis.com/?delimiter=/&prefix=98.0.4758.48/';
$xmlContents = file_get_contents($apiUrl);
if (!$xmlDom->loadXML($xmlContents)) {
throw new \Exception('Unable to parse the chromedriver file index API response as XML.');
}
$xpath = new \DOMXPath($xmlDom);
// **I tried several $query values here**
$fileEntries = $xpath->query($query, null, false);
if (!$fileEntries instanceof \DOMNodeList) {
throw new \Exception('Failed to evaulate the xpath into node list.');
}
echo "There are {$fileEntries->length} results\n";
foreach ($fileEntries as $node) {
/** @var \DOMNode $node */
var_dump($node->nodeName);
}
XPath $query
我试过:
/ListBucketResult/Contents
/Contents
//Contents
所有这些结果都是“有 0 个结果”。
如果我在 $query 中使用 *
,它将列出 <ListBucketResult>
根节点中的所有节点:
There are 10 results
string(4) "Name"
string(6) "Prefix"
string(6) "Marker"
string(9) "Delimiter"
string(11) "IsTruncated"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
最简单的方法是使用 nodeName
属性过滤节点。但我确实想知道我的 XPath 查询出了什么问题。我错过了什么?
您错过了 - 因为您没有在给定的视图中看到它 - 所有节点都在一个名称空间中,因为根元素 实际上 是
<ListBucketResult xmlns="http://doc.s3.amazonaws.com/2006-03-01">
所以这个元素及其所有子元素都在命名空间 http://doc.s3.amazonaws.com/2006-03-01
中。添加这样的命名空间
$xpath->registerNamespace("aws", "http://doc.s3.amazonaws.com/2006-03-01");
在 $xpath = new DOMXPath($xmlDom);
之后并像这样在您的 XPath 表达式中使用它
/aws:ListBucketResult/aws:Contents
应该可以解决您的问题。
我正在编写一个脚本来解析 this XML。
我想用 DOMDocument and DOMXpath 解析所有 <Contents>
节点。但是由于某种原因,我尝试的所有 XPath 查询都失败了。
我的代码:
<?php
$apiUrl = 'https://chromedriver.storage.googleapis.com/?delimiter=/&prefix=98.0.4758.48/';
$xmlContents = file_get_contents($apiUrl);
if (!$xmlDom->loadXML($xmlContents)) {
throw new \Exception('Unable to parse the chromedriver file index API response as XML.');
}
$xpath = new \DOMXPath($xmlDom);
// **I tried several $query values here**
$fileEntries = $xpath->query($query, null, false);
if (!$fileEntries instanceof \DOMNodeList) {
throw new \Exception('Failed to evaulate the xpath into node list.');
}
echo "There are {$fileEntries->length} results\n";
foreach ($fileEntries as $node) {
/** @var \DOMNode $node */
var_dump($node->nodeName);
}
XPath $query
我试过:
/ListBucketResult/Contents
/Contents
//Contents
所有这些结果都是“有 0 个结果”。
如果我在 $query 中使用 *
,它将列出 <ListBucketResult>
根节点中的所有节点:
There are 10 results
string(4) "Name"
string(6) "Prefix"
string(6) "Marker"
string(9) "Delimiter"
string(11) "IsTruncated"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
string(8) "Contents"
最简单的方法是使用 nodeName
属性过滤节点。但我确实想知道我的 XPath 查询出了什么问题。我错过了什么?
您错过了 - 因为您没有在给定的视图中看到它 - 所有节点都在一个名称空间中,因为根元素 实际上 是
<ListBucketResult xmlns="http://doc.s3.amazonaws.com/2006-03-01">
所以这个元素及其所有子元素都在命名空间 http://doc.s3.amazonaws.com/2006-03-01
中。添加这样的命名空间
$xpath->registerNamespace("aws", "http://doc.s3.amazonaws.com/2006-03-01");
在 $xpath = new DOMXPath($xmlDom);
之后并像这样在您的 XPath 表达式中使用它
/aws:ListBucketResult/aws:Contents
应该可以解决您的问题。