【发布时间】:2014-01-10 19:19:33
【问题描述】:
有了这个 XML
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<subject>Reference rates</subject>
<Sender>
<name>European Central Bank</name>
</Sender>
<Cube>
<Cube time='2013-12-20'>
<Cube currency='USD' rate='1.3655'/>
<Cube currency='JPY' rate='142.66'/>
</Cube>
</Cube>
</Envelope>
我可以像这样得到内部的Cube标签
from xml.etree.ElementTree import ElementTree
t = ElementTree()
t.parse('eurofxref-daily.xml')
day = t.find('Cube/Cube')
print 'Day:', day.attrib['time']
for currency in day:
print currency.items()
Day: 2013-12-20
[('currency', 'USD'), ('rate', '1.3655')]
[('currency', 'JPY'), ('rate', '142.66')]
问题在于上述 XML 是已定义命名空间的原始文件的清理版本
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time='2013-12-20'>
<Cube currency='USD' rate='1.3655'/>
<Cube currency='JPY' rate='142.66'/>
</Cube>
</Cube>
</gesmes:Envelope>
当我尝试获取第一个 Cube 标签时,我得到一个 None
t = ElementTree()
t.parse('eurofxref-daily.xml')
print t.find('Cube')
None
根标签包含命名空间
root = t.getroot()
print 'root.tag:', root.tag
root.tag: {http://www.gesmes.org/xml/2002-08-01}Envelope
它的孩子也是
for e in root.getchildren():
print 'e.tag:', e.tag
e.tag: {http://www.gesmes.org/xml/2002-08-01}subject
e.tag: {http://www.gesmes.org/xml/2002-08-01}Sender
e.tag: {http://www.ecb.int/vocabulary/2002-08-01/eurofxref}Cube
如果我在标签中包含命名空间,我可以获得Cube 标签
day = t.find('{http://www.ecb.int/vocabulary/2002-08-01/eurofxref}Cube/{http://www.ecb.int/vocabulary/2002-08-01/eurofxref}Cube')
print 'Day: ', day.attrib['time']
Day: 2013-12-20
但这真的很难看。除了在处理或进行字符串操作之前清理文件之外,还有一种优雅的方式来处理它吗?
【问题讨论】:
-
“定义的不存在的命名空间”是什么意思,URI 不必存在于网络上
-
@Mark 我的意思是那些 URI 会返回 404 not found。如果这不是问题,那么问题是另一个问题。
-
这对于命名空间来说不是问题,并且包含命名空间是按照 lxml(它是 ElementTree 的超集)tutorial 执行此操作的正确方法 - 这种使用命名空间的方式是比我在其他 XML API 中看到的要好得多
标签: python xml python-2.6 elementtree