minidom, encoding und encoder [erledigt]

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Hallo,

ich versuche mit minidom einen xml-String zu parsen. Wenn ich den String einfach mal mit print 'rausschreibe, sieht er ganz normal aus (ist auch klar, weil er in cp1252 kodiert ist). Ein Teil des Strings könnte so aussehen:

Code: Alles auswählen

<Name>Gerät 1</Name>
So weit, so schön. Wenn ich nun aber den Parser drauf loslasse, bekomme ich einen Fehler:

Code: Alles auswählen

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 9
Es sieht so aus, als käme der Parser mit dem 'ä' nicht klar, denn wenn ich es austausche, klappt es.

Frage 1:
Kann ich dem Parser mitteilen, was für ein encoding der String hat?

Frage 2:
Ich könnte den String umkodieren:

Code: Alles auswählen

import codecs
from xml.dom.minidom import parseString
boxXml = "<Name>Gerät 1</Name>".encode( "cp1252")
utf8Encoder = codecs.getencoder( "utf_8")
newXml = utf8Encoder( boxXml)[0]
dom1 = parseString( newXml)  # klappt
dom2 = parseString( boxXml)  # produziert obigen Fehler
Aber:
Woher weiß der encoder, wovon er ausgehen muß? Soll heißen:

Woher weiß der utf_8-encoder, daß er mein 'ä' bitteschön als utf_8-'ä' zu interpretieren hat? Es kann doch sein, daß die Zahl 'ä' (ein Wert zwischen 0 und 255, in c-Notation sozusagen) in einem anderen Zeichensatz als cp1252 vielleicht ein 'Z' repräsentiert.

Wenn der encoder also umcodiert, von einer Darstellung in eine andere, woher kennt er die Zuordnungen?

Vielleicht bin ich auf dem Holzweg und sehe den Baum im Wald nicht. Kann jemand von Euch Licht ins Dunkel bringen?

Gruß und Danke,

Christoph
Zuletzt geändert von ChrisGTJ am Freitag 27. Juni 2008, 15:48, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich denke du solltest - sofern das geht - einfach die XML-Standartkodierung UTF-8 verwenden.
Bei mir klappt das problemlos.

Ich denke daran liegt auch dein Problem, dass du im Code beschreibst: Du lässt den Parser auch nen cp1252-kodiertes Stückchen los ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Eben! Wenn Du weißt, dass Du eine cp-1251 codierte Datei einliest (die ja dann übrigens per definitionem nicht XML ist ;-) ), dann decodiere sie doch vor dem Parsen in Unicode. Das sollte Dein Problem lösen.
BlackJack

XML-Parser wollen Bytes und kein Unicode.
lunar

BlackJack hat geschrieben:XML-Parser wollen Bytes und kein Unicode.
Weil XML nämlich die Angabe des Encoding in der XML-Deklaration ermöglicht, so dass der Parser die Dekodierung automatisch vornehmen kann.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok, dann wird der Fehler also produziert, weil Das Encoding cp-1251 dem Parser nicht bekannt ist oder weil die Angabe in der Datei nicht simmt, richtig?
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Hallo,

danke für die Antworten.

Die Kodierung ist genau das Problem, wie mein Beispiel zeigt. Da der originale xml-String aus einem COM/DCOM-Objekt kommt, nehme ich mal cp1252 als Kodierung an. Jetzt noch mal die Kernfrage:

Woher weiß encode(), daß der String, von dem es ausgeht, in cp1252 kodiert ist?

Gruß,

Christoph

PS: Das Beispiel geht auch einfacher:

Code: Alles auswählen

from xml.dom.minidom import parseString
boxXml = "<Name>Gerät 1</Name>".encode( "cp1252")
utfXml = boxXml.encode( "utf_8")
dom1 = parseString( utfXml)  # klappt
dom2 = parseString( boxXml)  # produziert obigen Fehler
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ChrisGTJ hat geschrieben:Woher weiß encode(), daß der String, von dem es ausgeht, in cp1252 kodiert ist?
Weiß es nicht. Das ist ja eben der Punkt, warum man Encodings angeben muss.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Leonidas hat geschrieben:
ChrisGTJ hat geschrieben:Woher weiß encode(), daß der String, von dem es ausgeht, in cp1252 kodiert ist?
Weiß es nicht. Das ist ja eben der Punkt, warum man Encodings angeben muss.
Ja eben.

Vielleicht ist mein Problem ein Denkfehler:

Ich denke, daß die Methode encode() eine Übersetzung macht. Soll heißen, es nimmt einen Sack voller Bytes und baut ihn um, von encoding Typ A nach Typ B, indem alle Sachen aus A, die B nicht kennt, so dargestellt werden, daß B sie wieder kennt (alles klar? ;)). Aber: Stimmt diese Annahme überhaupt?

Gruß,

Christoph
BlackJack

Nein, die Annahme stimmt nicht. `encode()` wandelt *Unicode* in einen Sack voll Bytes um. Wenn Du einen Sack voll Bytes von einer Kodierung in die andere befördern willst, musst Du `decode()` und `encode()` nacheinander verwenden und beide Kodierungen explizit angeben.
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

BlackJack hat geschrieben:Nein, die Annahme stimmt nicht. `encode()` wandelt *Unicode* in einen Sack voll Bytes um. Wenn Du einen Sack voll Bytes von einer Kodierung in die andere befördern willst, musst Du `decode()` und `encode()` nacheinander verwenden und beide Kodierungen explizit angeben.
Nachdem es uns nun wie Schuppen aus den Haaren fällt, können wir nach Hause gehen. :)

Danke für die Info!

Christoph
Antworten