当我解析一个xml文件,然后将结果写入输出文件时,原始文件中任何有“ />”的地方都会添加一个空格。有什么办法可以防止它被创建?
我已经编写了一些python代码来更新xml文件中的几个字段,并认为我可以正常工作,但是在原始文件和更新文件之间的sdiff上运行后,我注意到不仅限于所需的行更新。 xml文件中任何有“ />”的地方都以“ />”为前缀。我注释掉了我的所有代码,除了parse命令然后是write命令,并且能够验证它似乎是parse或write命令引起了问题。
选择源XML文件的内容:更新的XML文件:
<QcfName/> <QcfName />
<Icf/> <Icf />
<Bidirectional/> <Bidirectional />
代码(注释所有其他代码):
tree = ET.parse(inFile)
tree.write(outFile)
我不需要将任何带有“ />”的条目更新为包含空格“ />”。
答案 0 :(得分:0)
我认为唯一的方法是重新定义ET._serialize_xml
并删除以下位置的硬编码空间:
write(" />")
基本上只是从ElementTree复制整个函数,删除空间,并用ET
更新任何函数/方法/类引用(例如Comment
变成ET.Comment
,_escape_cdata(text)
变成ET._escape_cdata(text)
,依此类推)
这还不是很漂亮,还需要维护一些其他内容。
示例...
XML输入(input.xml)
<doc>
<QcfName/>
<Icf/>
<Bidirectional/>
</doc>
Python
import xml.etree.ElementTree as ET
def local_serialize_xml(write, elem, qnames, namespaces,
short_empty_elements, **kwargs):
tag = elem.tag
text = elem.text
if tag is ET.Comment:
write("<!--%s-->" % text)
elif tag is ET.ProcessingInstruction:
write("<?%s?>" % text)
else:
tag = qnames[tag]
if tag is None:
if text:
write(ET._escape_cdata(text))
for e in elem:
local_serialize_xml(write, e, qnames, None,
short_empty_elements=short_empty_elements)
else:
write("<" + tag)
items = list(elem.items())
if items or namespaces:
if namespaces:
for v, k in sorted(namespaces.items(),
key=lambda x: x[1]): # sort on prefix
if k:
k = ":" + k
write(" xmlns%s=\"%s\"" % (
k,
ET._escape_attrib(v)
))
for k, v in sorted(items): # lexical order
if isinstance(k, ET.QName):
k = k.text
if isinstance(v, ET.QName):
v = qnames[v.text]
else:
v = ET._escape_attrib(v)
write(" %s=\"%s\"" % (qnames[k], v))
if text or len(elem) or not short_empty_elements:
write(">")
if text:
write(ET._escape_cdata(text))
for e in elem:
local_serialize_xml(write, e, qnames, None,
short_empty_elements=short_empty_elements)
write("</" + tag + ">")
else:
# CHANGED " />" TO "/>"
write("/>")
if elem.tail:
write(ET._escape_cdata(elem.tail))
ET._serialize_xml = local_serialize_xml
tree = ET.parse("input.xml")
tree.write("output.xml")
XML输出(output.xml)
<doc>
<QcfName/>
<Icf/>
<Bidirectional/>
</doc>