php – SimpleXML中的XPath,用于默认名称空间,无需前缀

我有一个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来解析所有内容.我的问题与如何处理认命名空间有关.

由于根元素上有一个认命名空间,我不能这样做

$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前缀?

使用空前缀不起作用($xml-> registerXPathNamespace(”,’http://www.example.com/ns/1.0′);).我可以指出认的命名空间,例如

$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源中,如果它们具有绑定到它们的命名空间,则它们的选择器必须以表单的基本XPath选择器为前缀NS:名称.请注意,ns是在XPath处理器中定义的前缀,而不是正在处理的文档,因此与XML表示中如何使用xmlns属性无关.

参见例如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确实包含“认命名空间”的概念,上面链接的XSLT页面也在XSLT 2.0的上下文中提到了这一点.

遗憾的是,PHP中的所有内置XML扩展都是在libxml2libxslt库之上构建的,这些库仅支持1.0版的XPath和XSLT.

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

(另外,值得注意的是,如果你在XML文档中有无前缀的属性,它们在技术上并不在认命名空间中,而是根本没有命名空间;请参阅XML Namespaces and Unprefixed Attributes以讨论命名空间规范的这种奇怪之处.)

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...