2010-08-04 5 views
11

Ich habe eine XML-Datei, die eine Codierung angibt, und ich verwende UnicodeDammit, um es in Unicode zu konvertieren (aus Gründen der Speicherung kann ich es nicht als String speichern). Ich übergebe es später an lxml, aber es weigert sich, die in der Datei angegebene Codierung zu ignorieren und es als Unicode zu analysieren, und es löst eine Ausnahme aus.Gibt es eine Möglichkeit, LXML zum Parsen von Unicode-Zeichenfolgen zu zwingen, die eine Codierung in einem Tag angeben?

Wie kann ich erzwingen lxml das Dokument zu analysieren? Dieses Verhalten scheint zu restriktiv zu sein.

Antwort

3

Grundsätzlich ist die Lösung zu tun:

if isinstance(mystring, unicode): 
    mystring = mystring.encode("utf-8") 

ernst. Gute Arbeit, lxml.

BEARBEITEN: Es stellt sich heraus, dass in diesem Fall lxml die Codierung automatisch falsch erkennt. Es scheint, dass ich manuell "charset" und "encoding" von der Seite suchen und entfernen muss.

15

Sie können nicht von Unicode-Strings analysieren UND haben eine Kodierungsdeklaration in der Zeichenfolge. Also, entweder Sie machen es eine codierte Zeichenfolge (wie Sie es offenbar nicht als Zeichenfolge speichern können, müssen Sie es vor dem Analysieren neu codieren. Oder Sie die Struktur als Unicode mit lxml selbst: , ohne XML-Deklaration . Sie können das Ergebnis wieder mit etree.fromunicode

siehe http://lxml.de/parsing.html#python-unicode-strings

bearbeiten leicht analysieren. Wenn anscheinend bereits die Unicode-String haben, und können nicht kontrollieren, wie das gemacht wurde Sie haben werde Codieren Sie es erneut, und stellen Sie dem Parser die von Ihnen verwendete Codierung zur Verfügung:

Dadurch wird sichergestellt, dass alles, was in der XML-Deklaration enthalten war, ignoriert wird, da der Parser immer utf-8 verwendet.

+0

Das ganze Problem ist, dass ich nicht einen Baum an erster Stelle bekommen, wenn ich es könnte ich wouldn‘ t haben irgendwelche Probleme ... –

+0

@Stavros Korokithakis, etree ist Modul, nicht der geparste Baum. –

+0

@Daniel Kluev: Ja, aber "Baum" ist ein Baum. –

0

Die Lösung wird die Zeichenfolge nicht neu codieren. Die Codierungsdeklaration in der Zeichenfolge kann etwas anderes als UTF8 sagen. Verändern Sie nicht blind zu utf8 und erwarten Sie, dass es die ganze Zeit funktioniert.

Die Lösung besteht darin, nur die Kodierungsdeklaration zu entfernen. Sie haben bereits eine Unicode-Zeichenfolge zur Hand, sie wird nicht mehr benötigt!

# this is from lxml/apihelpers.pxi 
RE_XML_ENCODING = re.compile(
    ur'^(<\?xml[^>]+)\s+encoding\s*=\s*["\'][^"\']*["\'](\s*\?>|)', re.U) 

RE_XML_ENCODING.sub("", broken_xml_string, count=1) 

Der schlimmste Fall (wo keine XML-Codierungsdeklaration gefunden wird) Zeitkomplexität hier ist O (n), was ziemlich schlecht ist (aber immer noch besser als blind binäre Codierung), damit ich bin offen für Vorschläge hier .

PS: Einige interessante Analysen von XML-Codierung Problem:

default encoding for XML is UTF-8 or UTF-16?

How default is the default encoding (UTF-8) in the XML Declaration?