首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果添加的元素没有命名空间,xpath.find()将找不到新元素

如果添加的元素没有命名空间,xpath.find()将找不到新元素
EN

Stack Overflow用户
提问于 2013-06-07 17:18:50
回答 1查看 330关注 0票数 3

今天,我偶然发现了xml.domxpath模块的一种特殊行为,我花了一段时间才弄明白它与XML名称空间有关:

代码语言:javascript
复制
from xml.dom import minidom
import xpath

zooXml = """<?xml version="1.0" encoding="utf-8"?>
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/></Compound>
</Zoo>"""

mydom = minidom.parseString(zooXml)
compound = xpath.findnode('/Zoo/Compound', mydom)
print compound.toxml() # as expected: <Compound><Chimp/></Compound>
print xpath.find("Chimp", compound) # as expected: [<DOM Element: Chimp at 0x24c0cc8>]

到目前为止一切正常,但是如果我现在添加另一个Chimp元素而不显式指定它的名称空间,xpath将找不到新元素:

代码语言:javascript
复制
newChimp = mydom.createElement("Chimp")
compound.appendChild(newChimp)
print compound.toxml() # ok, two chimps now: <Compound><Chimp/><Chimp/></Compound>
print xpath.find("Chimp", compound) # wait a second, that's still only one chimp: [<DOM Element: Chimp at 0x24a0d88>]

在重新解析修改后的XML之后,xpath将找到这两个元素:

代码语言:javascript
复制
mydom = minidom.parseString(mydom.toxml())
compound = xpath.findnode('/Zoo/Compound', mydom)
print xpath.find("Chimp", compound) # now it finds both chimps: [<DOM Element: Chimp at 0x24c9808>, <DOM Element: Chimp at 0x24c9888>]

此外,如果我使用命名空间创建新元素,xpath将在不重新解析的情况下找到它们:

代码语言:javascript
复制
babyChimp = mydom.createElementNS(mydom.firstChild.namespaceURI, "Chimp")
compound.appendChild(babyChimp)
print xpath.find("Chimp", compound) # that worked: [<DOM Element: Chimp at 0x24c9808>, <DOM Element: Chimp at 0x24c9888>, <DOM Element: Chimp at 0x24c9548>]

问题是:这种行为是正确的还是错误的?Chimp的名称空间不应该是隐式的吗?毕竟,无论我使用xml.dom.createElement()还是xml.dom.createElementNS(),生成的XML都是相同的。如果这是一个bug,那么它在哪里呢?在xml.domxpath

我在Python2.7.5和2.7.4的Windows发行版中观察到了这种行为,在这两种情况下我都使用了xpath模块0.1。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-20 21:50:31

简要地说:

问题是:这种行为是正确的还是错误的?

这种行为似乎是不正确的,或者至少是不受欢迎的,所以我会说这要么是bug,要么是未完成的功能。

Chimp的名称空间不应该是隐式的吗?

它在解析字符串时是隐式的,但在创建元素并将其添加到树中时不是隐式的。

毕竟,无论我使用xml.dom.createElement()还是xml.dom.createElementNS(),生成的

都是相同的。

生成的XML不相同,或者至少不应该相同。

,如果这是一个bug,那么它在哪里?

我猜toxml()方法中有一个bug,它没有输出第二个Chimp元素的空的默认名称空间,因此在重新解析修改后的文档时,它继承了Zoo元素的默认名称空间。

更准确地说:

首先,您的文档

代码语言:javascript
复制
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/></Compound>
</Zoo>

然后,您尝试查找Chimp元素,但是没有为它定义任何名称空间上下文。但是,在这种情况下,xpath模块似乎会从节点的文档元素初始化上下文,因此查找成功。

然后添加另一个Chimp元素,但不带名称空间,您的文档将成为

代码语言:javascript
复制
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp xmlns=""/></Compound>
</Zoo>

第二次find尝试只返回一个元素,因为另一个元素具有不同的名称空间。

我猜想这里会发生错误,所以toxml()方法的输出实际上是

代码语言:javascript
复制
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/></Compound>
</Zoo>

重新解析该文本会导致第二个Chimp元素继承与第一个元素相同的(默认)名称空间,因此第三个find将返回2个元素。

添加最后一个Chimp元素将导致文档变成

代码语言:javascript
复制
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/><Chimp xmlns='http://foo.bar/zoo'/></Compound>
</Zoo>

这完全与

代码语言:javascript
复制
<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/><Chimp/></Compound>
</Zoo>

同样,所有的Chimp元素都在相同的名称空间中,所以find会返回所有元素。

这个bug似乎是相关的:http://bugs.python.org/issue1371937尽管它的状态,但它实际上仍然是开放的,因为它是作为另一个打开的bug的副本关闭的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16980521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档