Encoding Probleme mit minidom

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ja klar, nach außen UTF-8 rausgeben ist ja kein Problem! Und intern mit Unicode arbeiten ist auch kein Problem. Also ist quasi die einzige Schwachstelle die "Eingabe"! Naja, ich hoffe mal, dass ich da mit UTF-8 keine Probleme haben werde.

Ist es nicht so, dass UTF-X Sachen für alle Zeichen der Welt ausgelegt ist? Wenn ja, sollte es doch prinzipiell keine Zeichen geben, die zumindest mal nicht interpretierbar wären! Damit wäre ja dann der Text ggf. schrottig in seiner Darstellung, wenn eben kein UTF-8 eingegeben worden ist, aber bei der Wandlung nach Unicode sollte es doch dann keine Probleme geben, sehe ich das richtig?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wenn du einen Text der, sagen wir mal in KOI8-R kodierst ist, versuchst mit UTF-8 in Unicode zu dekodieren bekommst du nur Garbage im Unicode-String. Das liegt daran, dass die Zeichen interpretiert werden und das was Я in KOI8-R ist, kann in UTF-8 ganz was anderes sein.

Code: Alles auswählen

>>> s = u"Я"
>>> s
u'\u042f'
>>> print s
Я
>>> s.encode('koi8-r')
'\xf1'
>>> _.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.4/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf1 in position 0: unexpected end of data
In dem Fall funktioniert es nicht einmal, da die KOI8-R Sequenz von Я kein gültiges UTF-8 ist.

Ergo: Nein, das das Unicode alle Zeichen darstellen kann heißt nicht, dass man auf einmal Bytestrings alle als UTF-8 ansehen kann. Dekodieren muss man sie immer mit dem richtigen Encoding.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok! Da ist ja wirklich mistig! Also am besten alle Eingaben versuchen aus dem erwarteteten Zeichencodec in Unicode zu wandeln und das ganze in nem try-catch Block und ggf. die Annahme quasi verweigern. Das sollte man mal in einem CGI-Tutorial erwähnen ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das würde ich nicht machen, ich halte es für nicht sonderlich schlau. Letztendlich wird durch das try-except *irgendein* Encoding gewählt, nicht das *richtige* sondern nur eines welches keine Exception wirft.

Ich gebe dir mal ein Beispiel.

Code: Alles auswählen

>>> bg = u"България"
>>> bg_utf8 = bg.encode('utf8')
>>> bg_utf8
'\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd0\xb8\xd1\x8f'
>>> bg_koi = bg.encode('koi8-r')
>>> bg_koi
'\xe2\xdf\xcc\xc7\xc1\xd2\xc9\xd1'
>>> print bg_koi
�������
>>> print bg_utf8
България
Ich erstelle hier einen Unicode-String mit "Bulgarien" als Inhalt. Dieser kommt als UTF-8 Bytefolge rein, weil mein Environment auf UTF-8 gestellt wird. Das passiert implizit, man kann es aber auch explizit machen. Danach erstelle ich zwei Byte-Strings: einen UTF-8 kodierten und einen mit KOI8-R kodierten (ich weiß nicht was man so üblicherweise für ein Encoding in Bulgarien her nimmt, ob es nun KOI8-R ist oder CP1251 oder DOS 866 oder ISO-8859-5 ist). Nun versuche ich beide auszugeben. Der KOI8-R kodierte Text erzeugt bei mir nur Fragezeichen, da meine Konsole UTF-8 erwartet und damit nichts anzufangen weiß (aber keine Ausnahmen wirft). Der UTF-8 kodierte Text wird hingegen einwandfrei angezeigt.

Wenn du nicht auch lauter falsch dekodierte Strings haben willst, dann solltest du ein Encoding festlegen welches du annimmst.
Und bevor du über try-except das Encoding zu raten versuchst, nimm besser `encodinghelper` oder `chardet`. Nur sei dir bewusst, dass man das Encoding eines Textes nur erraten kann, nicht aber es sicher bestimmen.

Edit: Oh, ich sehe dass da was vom Forum zerlegt wurde. Du kannst aber die \???-Escape-Sequenzen verwenden um die Strings einzugeben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben:Das würde ich nicht machen, ich halte es für nicht sonderlich schlau. Letztendlich wird durch das try-except *irgendein* Encoding gewählt, nicht das *richtige* sondern nur eines welches keine Exception wirft.

...

Wenn du nicht auch lauter falsch dekodierte Strings haben willst, dann solltest du ein Encoding festlegen welches du annimmst.
Da hast Du mich glaub ich missverstanden! Ich meinte ja, dass ich im try-except Block das Encoding versuche zu wandeln, welches ich erwarte! Sollte das nicht klappen, so erhalte ich einen Fehler und kann darauf reagieren! Ich wollte nicht endlich viele hintereinanderschachteln, um das richtige / erste ohne Exceptions zu wählen ;)
Und bevor du über try-except das Encoding zu raten versuchst, nimm besser `encodinghelper` oder `chardet`. Nur sei dir bewusst, dass man das Encoding eines Textes nur erraten kann, nicht aber es sicher bestimmen.
Ok, das werd ich mir mal ansehen, danke. Auch für das Beispiel. Ich werds mir morgen mal genauer ansehen und ausprobieren!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Da hast Du mich glaub ich missverstanden! Ich meinte ja, dass ich im try-except Block das Encoding versuche zu wandeln, welches ich erwarte! Sollte das nicht klappen, so erhalte ich einen Fehler und kann darauf reagieren!
Habe dich wirklich vorhin falsch verstanden. So passt es natürlich :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten