为什么在python中解析xml文件会在文件中有“/>”的地方增加空间?

2024-06-09 01:07:45 发布

您现在位置:Python中文网/ 问答频道 /正文

当我解析xml文件,然后将结果写入输出文件时,只要有“/>;”,就会添加一个空格在原始文件中。有没有什么方法可以阻止它被创建

我编写了一些python代码来更新xml文件中的几个字段,并认为一切正常,但在原始文件和更新文件之间运行sdiff之后,我注意到更新的不仅仅是所需的行。任何有“/>;”在xml文件中,它的前缀有一个空格“/>;”。我注释掉了除parse命令和write命令之外的所有代码,并且能够验证parse或write命令是否导致了问题

选择源XML文件的内容:更新的XML文件:

<QcfName/>                              <QcfName />
<Icf/>                                  <Icf />
<Bidirectional/>                        <Bidirectional />

代码(注释掉所有其他代码):

tree = ET.parse(inFile)

tree.write(outFile)

我不需要任何带有“/>;”的条目更新以包含空间“/>;”


Tags: 文件方法代码命令gttreeparsexml
1条回答
网友
1楼 · 发布于 2024-06-09 01:07:45

我认为这样做的唯一方法是重新定义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>

相关问题 更多 >