如何为此 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 我试过:

所有这些结果都是“有 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

应该可以解决您的问题。