Python:xpath.find()如果添加新元素时没有使用namesp,则找不到它们

2024-05-28 22:30:40 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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>]

{{3}如果不显式地指定另一个元素的名称空间,那么{3}如果不显式地添加另一个元素cdi},那么现在就不会找到新的元素了:

^{pr2}$

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

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将在不重新解析的情况下找到它们:

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都是相同的。如果这是个虫子,那它在哪里?在xml.dom还是在xpath中?在

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


Tags: 元素空间xmlelementxpathatdomprint
1条回答
网友
1楼 · 发布于 2024-05-28 22:30:40

简要说明:

The question is: is this behaviour correct or is it a bug?

这种行为似乎是不正确的,或者至少是不需要的,所以我想说它要么是bug,要么是未完成的特性。在

Shouldn't the namespace of Chimp be implicit?

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

After all, the XML generated will be the same, regardless of whether I use xml.dom.createElement() or xml.dom.createElementNS().

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

And if this is a bug, then where is it?

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

更准确地说:

首先你的文件是

<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/></Compound>
</Zoo>

然后尝试查找Chimp元素,但没有为其定义任何命名空间上下文。然而,在这种情况下,xpath模块从节点的document元素初始化上下文,因此查找成功。在

然后添加另一个Chimp元素,但是没有名称空间,那么您的文档就变成

^{pr2}$

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

我猜bug发生在这里,因此toxml()方法的输出实际上是

<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/></Compound>
</Zoo>

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

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

<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/><Chimp xmlns='http://foo.bar/zoo'/></Compound>
</Zoo>

完全相同于

<Zoo xmlns='http://foo.bar/zoo'>
  <Compound><Chimp/><Chimp/><Chimp/></Compound>
</Zoo>

同样,所有的Chimp元素都在同一个命名空间中,因此find将返回所有元素。在

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

相关问题 更多 >

    热门问题