Python:xml ElementTree(或lxml)中的命名空间
我想要读取一个旧的xml文件,对它进行处理然后保存。
这是我的代码:
from xml.etree import cElementTree as ET
NS = "{http://www.somedomain.com/XI/Traffic/10}"
def fix_xml(filename):
f = ET.parse(filename)
root = f.getroot()
eventlist = root.findall("%(ns)Event" % {'ns':NS })
xpath = "%(ns)sEventDetail/%(ns)sEventDescription" % {'ns':NS }
for event in eventlist:
desc = event.find(xpath)
desc.text = desc.text.upper() # do some editting to the text.
ET.ElementTree(root, nsmap=NS).write("out.xml", encoding="utf-8")
shorten_xml("test.xml")
我加载的文件内容是:
xmlns="http://www.somedomain.com/XI/Traffic/10"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.somedomain.com/XI/Traffic/10 10.xds"
在根标签下。
我遇到了以下与命名空间有关的问题:
- 如你所见,每次调用标签时,我都需要在前面加上命名空间才能获取子标签。
- 生成的xml文件开头没有
<?xml version="1.0" encoding="utf-8"?>
。 - 输出的标签像
<ns0:eventDescription>
,而我希望输出的是原始的<eventDescription>
,也就是开头没有命名空间。
这些问题该怎么解决呢?
2 个回答
1
为了回答你的问题,我来逐条解释:
你不能忽视命名空间。在使用
.findall()
的路径语法中是这样,使用“真实”的 xpath(lxml 支持的)也是一样:在那种情况下,你仍然需要使用一个前缀,并且还需要提供前缀和 URI 的映射关系。在调用
.write()
时,记得使用xml_declaration=True
和encoding='utf-8'
(在 lxml 中可用,但在标准库的 xml.etree 中从 Python 2.7 开始才有这个功能)。我相信 lxml 会按照你想要的方式工作。