2017-05-30 1 views
0

serialisieren Ich muss mit Legacy-Code arbeiten, die xml.dom.minidom verwenden (und ich kann nicht auf lxml migrieren).Kann nicht Minidom-Struktur mit Io-Modul

Ich möchte diese minimale Probe analysieren:

<body> 
    <p>English</p> 
    <p>Français</p> 
</body> 

Die folgende Funktion funktioniert perfekt:

import codecs 
import xml.dom.minidom 


def transform1(src_path, dst_path): 
    tree = xml.dom.minidom.parse(src_path) 
    # ... 
    with codecs.open(dst_path, mode="w", encoding="utf-8") as fd: 
     tree.writexml(fd, encoding="utf-8") 

Aber wenn ich io ändern, anstatt zu verwenden, geht alles schief:

Traceback (most recent call last): 
    File "/path/to/minidom_demo.py", line 23, in <module> 
    transform2("sample.xml", "result.xml") 
    File "/path/to/minidom_demo.py", line 18, in transform2 
    tree.writexml(fd, encoding="utf-8") 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/minidom.py", line 1747, in writexml 
    writer.write('<?xml version="1.0" encoding="%s"?>%s' % (encoding, newl)) 
TypeError: must be unicode, not str 

Wenn ich die Datei im Binärmodus (mode="wb") öffne ich habe ano ther Ausnahme-Sprichwort:

Traceback (most recent call last): 
    File "/path/to/minidom_demo.py", line 23, in <module> 
    transform2("sample.xml", "result.xml") 
    File "/path/to/minidom_demo.py", line 18, in transform2 
    tree.writexml(fd, encoding="utf-8") 
    ... 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/minidom.py", line 298, in _write_data 
    writer.write(data) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 4: ordinal not in range(128) 

Der Minidom Writer scheint Unicode nicht zu kennen.

Warum funktioniert es mit codecs?

Gibt es eine Möglichkeit, das zu beheben?

Antwort

0

Die writexml Methode scheint str immer dump. Das Lesen der Dokumentation sagt mir, dass das Argument encoding das Codierungsattribut nur dem XML-Header hinzufügt.

in Version geändert 2.3: Für den Document-Knoten, eine zusätzliches Schlüsselwort Argument Codierung verwendet werden kann, die Codierung Feld der XML Header angeben.

Sie können stattdessen versuchen:

fd.write(tree.toxml(encoding="utf-8").decode("utf-8")) 

Die oben wird die XML als UTF-8 speichern und gibt die Codierung in der XML-Header als auch.

Wenn Sie keine Kodierung angeben, wird sie dennoch als UTF-8 gespeichert, aber das Kodierungsattribut wird nicht in die Kopfzeile aufgenommen. obwohl

fd.write(tree.toxml()) 

Wenn Sie Codierung angeben, aber nicht decode(), wird es eine Ausnahme auslösen wie toxml() ein str zurück, die ganz seltsam.

TypeError: write() argument 1 must be unicode, not str