【问题标题】:Reading XML header encoding读取 XML 标头编码
【发布时间】:2014-11-05 22:07:02
【问题描述】:

我有许多 XML 文件,我想用脚本处理,将它们从它们所在的任何编码转换为 UTF-8。

使用this great answer 中给出的代码我可以进行转换,但是如何读取 XML 标头中给出的编码?

例如,我有很多文件已经是 UTF-8,应该不理会:

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

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

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

如何在 Python 中检测这些文件的标头中指定的 XML 编码?更好的是,在我检测并重新编码文件之后,我怎样才能将此 XML 标头更改为读取“utf-8”以避免将来对其进行处理?

【问题讨论】:

    标签: python xml encoding


    【解决方案1】:

    使用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 再次写出文件。

    【讨论】:

    • 有没有办法用 Python 的标准库做到这一点?
    • @PiotrDobrogost:您可以尝试使用expat parser,但如果您需要对整个文档进行重新编码,工作量会很大。
    • 我只对获取编码声明本身感兴趣。然而,根据docs Expat 不支持像 Python 那样多的编码,并且它的编码库无法扩展;它支持 UTF-8、UTF-16、ISO-8859-1 (Latin1) 和 ASCII。 我需要使用 ISO-8859-2 编码处理文档。事实上,Python 在标准库中仍然没有足够的 XML 工具。
    • 更多地考虑这个事实,即 Expat 不支持解析 ISO-8859-2 编码的 XML 文件并不一定意味着它不能单独处理获取编码声明,因为这是 SAX 解析器和 xml声明首先出现在文件中。事实证明这是可能的——见我的answer。
    【解决方案2】:

    如何检测这些标题中指定的 XML 编码 Python 中的文件?

    Rob Wolfe 的 solution 仅使用标准库:

    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)
    

    【讨论】:

    • 但是,正如您的 cmets 对我的回答所述,expat 实际上并不支持解码除 UTF-8、UTF-16、ISO-8859-1 以外的编解码器,并通过扩展,ASCII。所以不要尝试用它来重新编码其他编解码器中的文档,因为你会得到一个 Mojibake。
    • @MartijnPieters 对,这只是为了读取编码声明。
    【解决方案3】:

    我想扩展@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)
    

    【讨论】:

      猜你喜欢
      • 2016-11-11
      • 2018-08-03
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多