UTF-8

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
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Sonntag 4. November 2012, 11:08

Hi,

ich muss eine xml-Datei verarbeiten, in der das Zeichen "●" auftaucht. Python blockiert da, wenn ich das Zeichen ersetze, dann läuft es, sonst nicht.

Die xml-Datei ist laut Hersteller in UTF-8 codiert, ich dachte eigentlich, dass Python dann damit umgehen kann. Was muss ich meinem Quellcode hinzufügen, dass das Zeichen keinen Fehler verursacht, kann ich irgendwie die Codierung ändern???
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Sonntag 4. November 2012, 11:40

Woher sollen wir wissen, was du deinem Quellcode hinzufügen sollst wenn wir weder deinen Quellcode noch die konkrete Fehlermeldung kennen?
Benutzeravatar
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Sonntag 4. November 2012, 11:47

Ok, ich arbeite mit Python 3.2.2, was UTF-8 unterstützen sollte.

Die Fehlermeldung lautet:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\...\dienst.py", line 13, in <module>
    for line in f:
  File "C:\Python32\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in position 6755: character maps to <undefined>
Mir ist hier auch unklar, warum dort von byte die Rede ist, wo doch eine XML-Datei für mich nach einer normalen Textdatei mit Endung xml aussieht.

Im Quellcode öffne ich die xml-Datei und arbeite an der Datei:

Code: Alles auswählen

with open("content.xml") as f:
    ''' Bastle den Kopf, die Seite und den Fussbereich
    '''
    for line in f:

        content.append(line)

    content = "".join(content)

    # print(content)
    
    content = content.split("<draw:page")

    head = content[0]

    # print(len(content))
    
    content = "<draw:page" + content[1]

    content = content.split("</draw:page>")

    print(len(content))
    print("XXXX" * 400)
    
    page = content[0] + "</draw:page>"

    foot = content[1]

    if foot == "":

        foot = "</office:graphics></office:body></office:document-content>"
Der Quellcode-Abschnitt läuft nicht gut, scheint aber seine Aufgabe irgendwie zu erfüllen.

Ich arbeite an einer odg-Datei und will hier Änderungen automatisch vornehmen, Seiten einfügen und Text korrigieren. Dazu muss ich die Seite in ihre Bereiche Kopf-, Körper- und Fuß-Bereich zerlegen...
Benutzeravatar
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Sonntag 4. November 2012, 12:36

Problem scheint zu sein, dass ich Umlaute nicht richtig in die xml-Datei schreiben kann. Ich kann sie auch als ä, ö usw. eintragen, wenn ich in LibreOffice öffnen will, gibt es einen Fehler. Wer weiß Rat???
Benutzeravatar
/me
User
Beiträge: 3289
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sonntag 4. November 2012, 12:46

pixewakb hat geschrieben:Problem scheint zu sein, dass ich Umlaute nicht richtig in die xml-Datei schreiben kann. Ich kann sie auch als ä, ö usw. eintragen, wenn ich in LibreOffice öffnen will, gibt es einen Fehler. Wer weiß Rat???
Bist du dir auch völlig sicher, dass du die Datei in der gewünschten Kodierung (UTF-8) wegschreibst?

Es gibt übrigens sehr gute Bibliotheken zum Arbeiten mit XML-Dateien. Warum verwendest du stattdessen fehleranfällige String-Operationen?
BlackJack

Sonntag 4. November 2012, 12:47

@pixewakb: Hör am besten sofort auf XML-Dateien als Textdateien aufzufassen. Es sind nun mal keine einfachen Textdateien, sondern ein Format das einem Satz fester Regeln folgen muss, sonst ist es kein XML mehr. Deshalb gibt es Bibliotheken dafür. Nutze diese!

Ansonsten hast Du da ein Verständnisproblem bei Kodierungen und Unicode-Objekten. Du liest die Datei ein, dabei werden Bytes in Unicode dekodiert — Du gibst aber nirgends an nach welcher Kodierung das passieren soll. Dann wird die „des Systems” verwendet. Die wie man am Traceback deutlich sehen kann nicht UTF-8 sondern CP1252 ist. Kein Wunder dass das nicht gut geht.

Was zum lesen: HOWTO Avoid Being Called a Bozo When Producing XML
Benutzeravatar
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Sonntag 4. November 2012, 13:33

Dafür lohnt sich der Aufwand nicht. Ich muss es recht bald (heute) fertig machen, sieht danach aus, dass ich es händisch erledigen muss. Mit den Hilfen zum Decodieren kann ich momentan noch nichts anfangen und die Anleitungen zum Arbeiten mit XML-Werkzeugen - muss ich mir irgendwann ansehen - dafür reicht aber gerade die Zeit nicht.
Sirius3
User
Beiträge: 10908
Registriert: Sonntag 21. Oktober 2012, 17:20

Sonntag 4. November 2012, 13:37

Zum Lesen:

Code: Alles auswählen

with open("content.xml") as f:
    content=f.read().decode('utf8')
Benutzeravatar
Hyperion
Moderator
Beiträge: 7477
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sonntag 4. November 2012, 13:42

pixewakb hat geschrieben:Dafür lohnt sich der Aufwand nicht. Ich muss es recht bald (heute) fertig machen, sieht danach aus, dass ich es händisch erledigen muss. Mit den Hilfen zum Decodieren kann ich momentan noch nichts anfangen und die Anleitungen zum Arbeiten mit XML-Werkzeugen - muss ich mir irgendwann ansehen - dafür reicht aber gerade die Zeit nicht.
Was genau musst Du denn machen? Im Grunde genommen reduzieren XML-Parser und -Generatoren den Aufwand enorm... und so viel Einarbeitungszeit braucht es da gar nicht, da Du ja eh schon einen Anwendungsfall hast. Besser geht es ja gar nicht!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3289
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sonntag 4. November 2012, 14:01

Sirius3 hat geschrieben:

Code: Alles auswählen

with open("content.xml") as f:
    content=f.read().decode('utf8')
Ich würde die Datei direkt passend öffnen:

Code: Alles auswählen

with open('content.xml', encoding='UTF-8') as f:
    content = f.read()
Benutzeravatar
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Sonntag 4. November 2012, 14:12

Ich habe mir gerade erst einmal mit Notepad++ beholfen (Notbehelf) und die Codierung per Hand angepasst. Ich muss mal schauen, ob ich es einen Tag noch mal anders machen kann. Das musste jetzt gerade erst einmal so reichen.

Ich habe aktuell ca. 18 x 8 Schildchen, wo ich Texte ändern muss. Anfang kommender Woche könnten noch einmal deutlich mehr bei mir ankommen. Der Datenumfang ist so, dass ich das notfalls per Hand verändern kann. Auf dem Schreibtisch liegen noch einige andere Aufträge, so dass das jetzt gerade erst einmal so ging. Das Skript hat - mit der Nacharbeit in Notepad++ - gerade funktioniert, liefert aber jetzt auch wieder nur Fehlermeldungen.

Eure Vorschläge schaue ich mir einen Tag noch mal gesondert an; mit Codierung und Umlauten musste ich bislang nicht häufig arbeiten. Das wird sich in Zukunft ändern.

(...Eigentlich muss ich an LibreOffice Draw-Dateien ran...)
BlackJack

Sonntag 4. November 2012, 14:47

@pixewakb: Ich möchte nur noch mal Hyperions Aussage bekräftigen: Eine XML-Bibliothek macht die Bearbeitung von XML wesentlich einfacher als wenn man sie als Textdatei auffasst und am Inhalt herumdoktort. Beim Lesen kommt sie mit allem klar was einem bei XML so über den Weg laufen kann und beim Schreiben garantiert sie, das auch tatsächlich wieder XML erzeugt wird, und nicht etwas was so ähnlich ist, aber von keinem Programm das XML erwartet wieder gelesen werden kann. Und man kann direkt auf der Struktur des Dokuments arbeiten, also gezielt und *robust* auf Elemente und ihre Inhalte zugreifen.
lunar

Sonntag 4. November 2012, 15:49

@pixewakb Dir muss auch klar sein, dass LibreOffice wie jedes andere XML-verarbeitende Programm wohlgeformtes XML voraussetzt. Erzeugst Du fehlerhaftes XML, was beim Herumdoktokren mit Zeichenketten gut möglich ist, dann fliegt Dir das LibreOffice-Dokument beim Öffnen um die Ohren, und Du musst dann manuell jedes fehlerhafte Dokument korrigieren, da Du auch mit anderen XML-Tools nichts mehr retten kannst.

Das kostet Dich im Falle des Falls sicherlich mehr Zeit als einmal ein ordentliches Skript zu schreiben, dass XML mithilfe einer entsprechenden Bibliothek verarbeitet und unter Garantie korrekte XML-Dokument ausgibt. Die entsprechende ElementTree-Bibliothek aus der Standardbibliothek ist auch nicht so kompliziert, dass man sich nicht in einer halben Stunde einarbeiten könnte.

Es ist letztlich Deine Entscheidung, aber Du musst am Ende auch für Dein Programm und dessen Ausgabe gerade stehen.
Benutzeravatar
pyFan
User
Beiträge: 22
Registriert: Sonntag 4. Januar 2009, 15:44

Montag 5. November 2012, 20:38

Hallo pixewakb,

Vielleicht hilft dir die Klasse ResolveODF.
Sie soll es erleichtern, ODF Dateiene zu parsen und zu verändern.

Hier eine kleine Erläuterung, die Links stehen am Dateiende:

http://www.rotweinundradieschen.de/pyco ... slides.pdf

Der Link ist von dieser Seite:

https://2012.de.pycon.org/programm/sche ... ssions/37/

Gruss

Pyfan
Benutzeravatar
pixewakb
User
Beiträge: 1250
Registriert: Sonntag 24. April 2011, 19:43

Dienstag 6. November 2012, 22:54

Ich habe es mit "meinem" Verfahren hinbekommen und die XML-Datei konnte korrekt geöffnet werden. Falls es wen interessiert, die content.xml-Datei einer ODF-Datei ist ziemlich simpel aufgebaut und kann somit auch ohne XML-Bibliothek bearbeitet werden. Das Ergebnis war gerade korrekt. - Ihr habt schon Recht, ich werde Richtung XML-Werkzeuge und -Bibs wechseln! :oops:

Mich stört momentan, dass ich viel per Hand vorbereiten musste und mit der Codierung bzw. Decodierung Probleme habe. Das manuell zu tun, ist auf Dauer auch keine Lösung. Für diese Aufgabe hier ging das.

Jedenfalls werde ich mir mal die XML-Werkzeuge ansehen; Dokumentationen suchen und mich einarbeiten. Mir fällt momentan noch schwer, es mir vorzustellen, weshalb ich da gewisse Hemmungen habe. Einen String und die Manipulationen daran kann ich mir vorstellen. Wie ich in XML einen "Zweig" (?) klone, wo der sich dann befindet und wie ich Änderungen daran vornehme, kann ich mir nicht vorstellen. Werde damit - wenn ich wieder etwas Zeit habe - mal rumexperimentieren...
Antworten