读取XML头部编码

5 投票
3 回答
6642 浏览
提问于 2025-04-21 04:50

我有一些XML文件想用脚本处理,把它们从当前的编码转换成UTF-8。

根据这个很棒的回答里的代码,我可以完成转换,但我该如何读取XML头部里指定的编码呢?

比如,我有很多文件已经是UTF-8编码的,这些文件就不需要处理:

<?xml version="1.0" encoding="utf-8"?>

但是,我还有很多文件是需要转换的:

<?xml version="1.0" encoding="windows-1255"?>

我该如何在Python中检测这些文件头部指定的XML编码呢?更好的是,在我检测并重新编码这些文件后,如何将这个XML头部改成“utf-8”,这样以后就不用再处理它了?

3 个回答

0

我想进一步解释一下@PiotrDobrogost的回答,实际上写一个类来获取XML文档的编码:

from xml.parsers import expat

class XmlParser(object):
    '''class used to retrive xml documents encoding
    '''

    def get_encoding(self, xml):
        self.__parse(xml)
        return self.encoding

    def __xml_decl_handler(self, version, encoding, standalone):
        self.encoding = encoding

    def __parse(self, xml):
        parser = expat.ParserCreate()
        parser.XmlDeclHandler = self.__xml_decl_handler
        parser.Parse(xml)

下面是它使用的一个例子:

xml = """<?xml version='1.0' encoding='iso-8859-1'?>
    <book>
        <title>Title</title>
        <chapter>Chapter 1</chapter>
    </book>"""
parser = XmlParser()
encoding = parser.get_encoding(xml)
2

我怎么能在Python中检测这些文件头部指定的XML编码呢?

这是Rob Wolfe提供的一个解决方案,只使用了标准库:

from xml.parsers import expat

s = """<?xml version='1.0' encoding='iso-8859-1'?>
       <book>
           <title>Title</title>
           <chapter>Chapter 1</chapter>
       </book>"""

class MyParser(object):
    def XmlDecl(self, version, encoding, standalone):
        print "XmlDecl", version, encoding, standalone

    def Parse(self, data):
        Parser = expat.ParserCreate()
        Parser.XmlDeclHandler = self.XmlDecl
        Parser.Parse(data, 1)

parser = MyParser()
parser.Parse(s)
5

使用 lxml 来进行解析;这样你就可以获取原始的编码方式,方法是:

from lxml import etree

with open(filename, 'r') as xmlfile:
    tree = etree.parse(xmlfile)
    if tree.docinfo.encoding == 'utf-8':
        # already in correct encoding, abort
        return

然后你可以用 lxml 再把文件保存成 UTF-8 格式。

撰写回答