Python lxml iterfind使用命名空间但前缀为None

6 投票
2 回答
4732 浏览
提问于 2025-04-16 20:11

我想对那些有命名空间但没有前缀的元素使用 iterfind() 方法。我希望能这样调用:

iterfind([标签名])iterfind([标签名], [命名空间字典])

我不想每次都这样输入标签:

"{%s}标签名" % tree.nsmap[None]

详细信息

我正在处理一个来自 Google API 的 XML 响应。根节点定义了几个命名空间,其中一个没有前缀: xmlns="http://www.w3.org/2005/Atom"

看起来当我尝试在我的 etree 中搜索时,对于带有前缀的元素,一切都按我预期的方式工作。例如:

>>> for x in root.iterfind('dxp:segment'): print x
...
<Element {http://schemas.google.com/analytics/2009}segment at 0x1211b98>
<Element {http://schemas.google.com/analytics/2009}segment at 0x1211d78>
<Element {http://schemas.google.com/analytics/2009}segment at 0x1211a08>
>>>

但是当我尝试搜索没有前缀的东西时,搜索不会自动添加 root.nsmap[None] 的命名空间。例如:

>>> for x in root.iterfind('entry'): print x
...
>>>

即使我尝试把命名空间映射作为 iterfind 的可选参数传入,它也不会附加命名空间。

2 个回答

0

我发现你可以简单地添加一个空字符串,这样就可以映射到默认的命名空间(在Python 3.9中验证过):

nsmap = {'': 'http://www.w3.org/2005/Atom'}
for x in root.iterfind('entry', namespaces=nsmap):
    print(x)
3

试试这个:

for x in root.iterfind('{http://www.w3.org/2005/Atom}entry'):
    print x

想了解更多信息,可以看看文档:http://lxml.de/tutorial.html#namespaces

如果你不想输入那么多内容,想提供一个命名空间映射,你总是需要使用一个前缀,比如这样:

nsmap = {'atom': 'http://www.w3.org/2005/Atom'}
for x in root.iterfind('atom:entry', namespaces=nsmap):
    print x

如果你想使用xpath,也是同样的道理。

在文档中使用的前缀是什么并不重要,关键是你要指定元素的完整名称。你可以用大括号的方式写出完整的URI,或者使用一个映射到URI的前缀。

撰写回答