用于默认名称空间的SimpleXML中的XPath不需要前缀 [英] XPath in SimpleXML for default namespaces without needing prefixes

查看:100
本文介绍了用于默认名称空间的SimpleXML中的XPath不需要前缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an XML document that has a default namespace attached to it, eg

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

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

In reality this is a complex XML document that conforms to a complex schema. My job is to parse out some data from it. To aid me, I have a spreadsheet of XPath. The XPath is rather deeply nested, eg

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

生成XPath的人是架构专家,因此我假设我无法简化它或使用对象遍历快捷方式.

The person who generate the XPath is an expert in the schema, so I am going with the assumption that I can't simplify it, or use object traversal shortcuts.

我正在使用 SimpleXML 来解析所有内容.我的问题与如何处理默认名称空间有关.

I am using SimpleXML to parse everything out. My problem has to do with how the default namespace gets handled.

由于根元素上存在默认的命名空间,所以我不能这样做

Since there is a default namespace on the root element, I can't just do

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

我必须注册名称空间,并将其分配给前缀,然后在我的XPath中使用前缀,例如

I have to register the namespace, assign it to a prefix, and then use the prefix in my XPath, eg

$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]');

从长远来看,添加前缀将是无法管理的.

Adding the prefixes isn't going to be manageable in the long run.

是否有适当的方法来处理默认名称空间,而无需在XPath中使用前缀?

Is there a proper way to handle default namespaces without needing to using prefixes with XPath?

使用空前缀不起作用($xml->registerXPathNamespace('', 'http://www.example.com/ns/1.0');).我可以删除默认的名称空间,例如

Using an empty prefix doesn't work ($xml->registerXPathNamespace('', 'http://www.example.com/ns/1.0');). I can string out the default namespace, 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版中

From a bit of reading online, this is not restricted to any particular PHP or other library, but to XPath itself - at least in XPath version 1.0

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

XPath 1.0 does not include any concept of a "default" namespace, so regardless of how the element names appear in the XML source, if they have a namespace bound to them, the selectors for them must be prefixed in basic XPath selectors of the form ns:name. Note that ns is a prefix defined within the XPath processor, not by the document being processed, so has no relationship to how xmlns attributes are used in the XML representation.

例如参见此常见的XSLT错误"页面,谈论与之密切相关的XSLT 1.0:

See e.g. this "common XSLT mistakes" page, talking about the closely related XSLT 1.0:

要访问XPath中的命名空间元素,必须为它们的命名空间定义一个前缀. [...]不幸的是,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.

根据一个类似问题的答案,XPath 2.0 确实包括默认名称空间",并且上面链接的XSLT页面在XSLT 2.0的上下文中也提到了这一点.

According to an answer to a similar question, XPath 2.0 does include a notion of "default namespace", and the XSLT page linked above mentions this also in the context of XSLT 2.0.

不幸的是,PHP中的所有内置XML扩展都是基于 libxml2 libxslt 库,这些库仅支持1.0版的XPath和XSLT.

Unfortunately, all of the built-in XML extensions in PHP are built on top of the libxml2 and libxslt libraries, which support only version 1.0 of XPath and XSLT.

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

So other than pre-processing the document not to use namespaces, your only option would be to find an XPath 2.0 processor that you could plug in to PHP.

(顺便说一句,值得注意的是,如果您在XML文档中没有前缀的属性,从技术上讲,它们不在默认名称空间中,而是根本没有名称空间;请参见 XML命名空间和未前缀属性,以讨论命名空间规范的这种怪异.)

(As an aside, it's worth noting that if you have unprefixed attributes in your XML document, they are not technically in the default namespace, but rather in no namespace at all; see XML Namespaces and Unprefixed Attributes for discussion of this oddity of the Namespace spec.)

这篇关于用于默认名称空间的SimpleXML中的XPath不需要前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆