使用LXML编写XML标头

Naf*_*Kay 6 python xml lxml elementtree

我目前正在编写一个脚本,将一堆XML文件从各种编码转换为统一的UTF-8.

我首先尝试使用LXML确定编码:

def get_source_encoding(self):
    tree = etree.parse(self.inputfile)
    encoding = tree.docinfo.encoding
    self.inputfile.seek(0)
    return (encoding or '').lower()
Run Code Online (Sandbox Code Playgroud)

如果那是空白的,我尝试从chardet以下方面获取:

def guess_source_encoding(self):
    chunk = self.inputfile.read(1024 * 10)
    self.inputfile.seek(0)
    return chardet.detect(chunk).lower()
Run Code Online (Sandbox Code Playgroud)

然后我codecs用来转换文件的编码:

def convert_encoding(self, source_encoding, input_filename, output_filename):
    chunk_size = 16 * 1024

    with codecs.open(input_filename, "rb", source_encoding) as source:
        with codecs.open(output_filename, "wb", "utf-8") as destination:
            while True:
                chunk = source.read(chunk_size)

                if not chunk:
                    break;

                destination.write(chunk)
Run Code Online (Sandbox Code Playgroud)

最后,我正在尝试重写XML标头.如果最初是XML标头

<?xml version="1.0"?>
Run Code Online (Sandbox Code Playgroud)

要么

<?xml version="1.0" encoding="windows-1255"?>
Run Code Online (Sandbox Code Playgroud)

我想把它变成

<?xml version="1.0" encoding="UTF-8"?>
Run Code Online (Sandbox Code Playgroud)

我目前的代码似乎不起作用:

def edit_header(self, input_filename):
    output_filename = tempfile.mktemp(suffix=".xml")

    with open(input_filename, "rb") as source:
        parser = etree.XMLParser(encoding="UTF-8")
        tree = etree.parse(source, parser)

        with open(output_filename, "wb") as destination:
            tree.write(destination, encoding="UTF-8")
Run Code Online (Sandbox Code Playgroud)

我正在测试的文件有一个没有指定编码的标头.如何使用指定的编码正确输出标题?

Rob*_*obᵩ 7

尝试:

tree.write(destination, xml_declaration=True, encoding='UTF-8')
Run Code Online (Sandbox Code Playgroud)

来自API文档:

xml_declaration控制是否应将XML声明添加到文件中.使用False了永远,True为始终,None仅当不US-ASCII或UTF-8(默认为None).

来自ipython的示例:

In [15]:  etree.ElementTree(etree.XML('<hi/>')).write(sys.stdout, xml_declaration=True, encoding='UTF-8')
<?xml version='1.0' encoding='UTF-8'?>
<hi/>
Run Code Online (Sandbox Code Playgroud)

经过反思,我觉得你太努力了.lxml自动检测编码并根据该编码正确解析文件.

所以你真正要做的事情(至少在Python2.7中)是:

def convert_encoding(self, source_encoding, input_filename, output_filename):
    tree = etree.parse(input_filename)
    with open(output_filename, 'w') as destination:
        tree.write(destination, encoding='utf-8', xml_declaration=True)
Run Code Online (Sandbox Code Playgroud)