为什么xml.etree.ElementTree不支持名称空间URI大小写更改

时间:2014-07-21 18:26:02

标签: python xml elementtree

我正在尝试解析XML,其中同一命名空间的URI没有使用相同的情况。 (一些xml所有者决定使用小写URI)。如果我使用一种类型的URI解析数据,然后使用另一种类型的数据解析数据,虽然我更新ns字典以匹配文档URI,解析器仍然无法找到我的数据...这是一个示例:

from cStringIO import StringIO
import xml.etree.ElementTree as ET

DATA_lc = '''<?xml version="1.0" encoding="utf-8"?>
<container xmlns:roktatar="http://www.example.com/lower/case/bug">
<item>
   <roktatar:author>Boby Mac Gallinger</roktatar:author>
</item>
</container>'''

DATA_UC = '''<?xml version="1.0" encoding="utf-8"?>
<container xmlns:roktatar="http://www.example.com/Lower/Case/Bug">
<item>
   <roktatar:author>John-John Le Grandiosant</roktatar:author>
</item>
</container>'''

tree = ET.parse(StringIO(DATA_lc))
root = tree.getroot()
ns = {'roktatar': 'http://www.example.com/lower/case/bug'}
for item in root.iter('item'):
    print item.find('roktatar:author', namespaces=ns).text.strip()

tree = ET.parse(StringIO(DATA_UC))
root = tree.getroot()
ns = {'roktatar': 'http://www.example.com/Lower/Case/Bug'}
for item in root.iter('item'):
    print item.find('roktatar:author', namespaces=ns).text.strip()

如果每个解析块都是自己处理的,那么数据会被正确收集,但如果它们彼此相邻,则第二个解析块总是会失败。我错过了重置/清理文件之间的解析器?这是一个Bug吗?

由于

1 个答案:

答案 0 :(得分:2)

ElementTree搜索代码解析find()的参数和XPath表达式的相关函数,缓存生成的封闭函数以供重用。

当您搜索roktatar:author时,该表达式会被缓存为'{http://www.example.com/lower/case/bug}author'的搜索,但在您的第二个文档中,绑定已更改。

换句话说,ElementTree假定相同的名称空间前缀始终映射到相同的名称空间URI。

此问题的更好解决方案是在此处使用不同的前缀,例如roktatar_uc作为网址的标题案例版本:

ns = {'roktatar_uc': 'http://www.example.com/Lower/Case/Bug'}
for item in root.iter('item'):
    print item.find('roktatar_uc:author', namespaces=ns).text.strip()

但如果这不是一个选项,则必须清除缓存:

from xml.etree import ElementPath

ElementPath._cache.clear()