我正在尝试解析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吗?
由于
答案 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()