php - SimpleXML 中用于默认 namespace 的 XPath,无需前缀

标签 php xml xpath namespaces simplexml

我有一个 XML 文档,它附加了一个默认的命名空间,例如

<foo xmlns="http://www.example.com/ns/1.0">
...
</foo>

实际上,这是一个符合复杂模式的复杂 XML 文档。我的工作是从中解析出一些数据。为了帮助我,我有一个 XPath 电子表格。 XPath 嵌套很深,例如

level1/level2/level3[@foo="bar"]/level4[@foo="bar"]/level5/level6[2]

生成 XPath 的人是模式方面的专家,所以我假设我无法简化它,或者使用对象遍历快捷方式。

我正在使用 SimpleXML解析一切。我的问题与默认 namespace 的处理方式有关。

因为在根元素上有一个默认的命名空间,我不能这样做

$xml = simplexml_load_file($somepath);
$node = $xml->xpath('level1/level2/level3[@foo="bar"]/level4[@foo="bar"]/level5/level6[2]');

我必须register the namespace ,将其分配给一个前缀,然后在我的 XPath 中使用该前缀,例如

$xml = simplexml_load_file($somepath);
$xml->registerXPathNamespace('myns', 'http://www.example.com/ns/1.0');
$node = $xml->xpath('myns:level1/myns:level2/myns:level3[@foo="bar"]/myns:level4[@foo="bar"]/myns:level5/myns:level6[2]');

从长远来看,添加前缀是不可管理的。

是否有一种无需使用 XPath 前缀即可处理默认 namespace 的正确方法?

使用空前缀不起作用 ($xml->registerXPathNamespace('', 'http://www.example.com/ns/1.0');)。我可以串出默认的命名空间,eg

$xml = file_get_contents($somepath);
$xml = str_replace('xmlns="http://www.example.com/ns/1.0"', '', $xml);
$xml = simplexml_load_string($xml);

但这是在回避问题。

最佳答案

从一些在线阅读来看,这并不局限于任何特定的 PHP 或其他库,而是 XPath 本身——至少在 XPath 1.0 版中是这样

XPath 1.0 不包含任何“默认”命名空间的概念,因此无论元素名称如何出现在 XML 源中,如果它们绑定(bind)了命名空间,则它们的选择器必须在基本 XPath 选择器中添加前缀形式为 ns:name。请注意,ns 是在 XPath 处理器中定义的前缀,而不是由正在处理的文档定义的,因此与 xmlns 属性在 XML 表示中的使用方式无关。

参见例如this "common XSLT mistakes" page ,谈论密切相关的 XSLT 1.0:

To access namespaced elements in XPath, you must define a prefix for their namespace. [...] Unfortunately, XSLT version 1.0 has no concept similar to a default namespace; therefore, you must repeat namespace prefixes again and again.

根据 an answer to a similar question , XPath 2.0 确实包含“默认 namespace ”的概念,并且上面链接的 XSLT 页面也在 XSLT 2.0 的上下文中提到了这一点。

不幸的是,PHP 中的所有内置 XML 扩展都是构建在 libxml2 之上的和 libxslt库,仅支持 1.0 版的 XPath 和 XSLT。

因此,除了预处理文档以不使用命名空间之外,您唯一的选择是找到一个可以插入 PHP 的 XPath 2.0 处理器。

(顺便说一句,值得注意的是,如果您的 XML 文档中有未加前缀的属性,它们在技术上不在默认 namespace 中,而是根本不在任何 namespace 中;参见 XML Namespaces and Unprefixed Attributes用于讨论命名空间规范的这种奇怪之处。)

关于php - SimpleXML 中用于默认 namespace 的 XPath,无需前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21143846/

相关文章:

html - XML文件中的url是什么意思

java - 迭代 java DOM 中的所有 XML 节点生成

xslt - 如何匹配XSL中包含字符串的属性?

xpath:限制祖先的范围以计算特定节点内具有特定父级的元素

php - Laravel:从 url 中删除 public,同时保持项目独立

javascript - 将 DIV 分配给 php 变量并在多个隐藏输入上循环

android - 在只有 2 列的 TableRow 中设置 3 个 TextView - Android

java - 从 xml 文件执行验证时出错

php - 如何使用类似于pdo的mysqli一次插入多条记录

php - 参数化查询的例子