我需要整理一段代码,将可能很大的XML文件解析为自定义Python对象。这个想法大致如下:
from lxml import etree
for e, tag in etree.iterparse(source, tag='Foo'):
print tag.xpath('bar/baz')[42] # there's actually a function call here
问题是,一些文档有一个名称空间声明,有些文档没有。这意味着在上面的代码中,tag='Foo'
和xpath
部分都无效。
现在我一直在忍受丑陋的
for e, tag in etree.iterparse(source):
if tag.tag.endswith('Foo'):
print tag.xpath('*[local-name()="bar"]/*[local-name()="baz"]')[42]
但是这太可怕了,即使它工作正常我也想要把它弄好。 (我想它也应该慢一些。)
有没有办法编写使用iterparse
来解决这两种情况的合理代码?
现在我只能考虑捕获start-ns
和end-ns
事件并更新“状态保持”变量,我必须将其传递给在循环内调用的函数来完成工作。然后,该函数将相应地构造xpath
个查询。这有点道理,但我想知道是否有更简单的方法。
P.S。我显然已经尝试过搜索,但是没有找到一个既可以使用也可以不使用命名空间的解决方案。我也接受一个消除XML命名空间的解决方案,但前提是它不会在整个过程中将整个树存储在RAM中。
答案 0 :(得分:2)
所有元素都有.nsmap
映射属性;用它来检测命名空间并相应地进行分支。