【问题标题】:How to correctly write a DOMXPath query for this XML?如何为此 XML 正确编写 DOMXPath 查询?
【发布时间】:2022-01-18 12:57:35
【问题描述】:

我正在编写一个脚本来解析this XML

我想用DOMDocumentDOMXpath 解析所有<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 中使用 *,它将列出 &lt;ListBucketResult&gt; 根节点内的所有节点:

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 查询出了什么问题。我错过了什么?

【问题讨论】:

    标签: php xml dom xpath


    【解决方案1】:

    你错过了 - 因为你没有在给定的视图中看到它 - 所有节点都在一个命名空间中,因为根元素 真的

    <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
    

    应该可以解决你的问题。

    【讨论】:

    • 不幸的是,URL doc.s3.amazonaws.com/2006-03-01 给了我一个“拒绝访问”的响应。
    • XML 命名空间的 URI不必是有效的。见here
    • 谢谢!这有点不直观。节点实际上没有aws: 前缀(或任何其他前缀),所以我认为没有必要注册命名空间。
    猜你喜欢
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多