php - 具有冲突的 XML 命名空间前缀的 XPath 行为
问题描述
考虑以下 XML:
<?xml version="1.0" encoding="utf-8"?>
<movies xmlns:en="http://english-language.com/">
<en:movie>
<title>The Godfather</title>
</en:movie>
<en:movie>
<title>Saving Private Ryan</title>
</en:movie>
<something-something xmlns:en="http://english.com/">
<en:movie>
<title>The Fellowship of the Ring</title>
</en:movie>
</something-something>
</movies>
下面的代码将匹配教父和拯救大兵瑞恩。但为什么?我预计它会失败。似乎该查询忽略了命名空间名称 (URI) 以支持命名空间前缀
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('en', 'http://complete-nonsense');
$elements = $xpath->query("//en:movie");
我希望下面的代码与The Fellowship of the Ring相匹配,但它再次与教父和拯救大兵瑞恩相匹配。
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('en', 'http://english.com/');
$elements = $xpath->query("//en:movie");
只是现在 URI 似乎有所不同,现在它与The Fellowship of the Ring相匹配。
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('english', 'http://english.com/');
$elements = $xpath->query("//english:movie");
这是为什么?PHP的实现有问题还是什么?
解决方案
DOMXpath::evaluate()
/DOMXpath::query()
在手动注册的之上注册当前上下文节点的命名空间定义。基本上,文档将覆盖前缀的命名空间。第三个参数(因为 PHP >= 5.3.3)可以禁用自动注册:
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('en', 'http://english.com/');
// the xmlns:en from the document element overrides the registration
var_dump($xpath->evaluate('normalize-space(//en:movie)'));
// automatic registration disabled - works correctly
var_dump($xpath->evaluate('normalize-space(//en:movie)', NULL, FALSE));
输出:
string(13) "The Godfather"
string(26) "The Fellowship of the Ring"
推荐阅读
- c++ - 如何在 C++ 中使用 OpenSSL 库实现 EVP_aes_256_cbc?
- machine-learning - 我应该为回归问题进行归一化还是标准化?
- c# - 如何将文件从一个 FTP 移动到另一个 FTP?
- module - 如何在编译时以程序方式构造属性的值?
- javascript - 当我尝试使用 RDB 时发生 Firebase 数据库 URL 错误
- python - 无法在仅 tensorflow CPU 安装上加载动态库“cudart64_101.dll”
- ios - SwiftUI-如何在 swfitUI 中为某个时间间隔制作动画图像?
- ubuntu - Tomcat 9 - Linux Ubuntu 18.04 中的位置
- r - R package psych 组合后两个均值在一个变量中
- python-3.x - 如何使用 matplotib.dates.date2num 获取条形图中条形的宽度?