Umbrüche werden in XML geschrieben

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
Jimyx
User
Beiträge: 4
Registriert: Mittwoch 4. September 2013, 12:58

Hallo zusammen,
ich habe da ein Problem beim erzeugen einer XML-Datei. Ich erzeuge eine XML-Datei mit lxml. Hier ist der Quelltext:

Code: Alles auswählen

        root = etree.Element("search", attrib={"id":"1"}) 
        results= etree.Element('results') 
        country= etree.Element('country')
        country.text = 'Germany'
        root.append(country)

        output_file = "C:/xmltestthing.xml"
        file = open(output_file,"w")
        t = etree.tostring(root, pretty_print=True, xml_declaration=True, encoding='UTF-8')
        t = str(t)
        file.write(t)
        file.close()
Es kommt folgende XML raus:

Code: Alles auswählen

b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<search id="1">\n  <country>Germany</country>\n</search>\n'
Warum werden die Umbrüche nicht durchgeführt sondern nur mit \n dargestellt ? Wie bekomme ich das Problem in den Griff ? Ich habe es zuvor mit minidom probiert aber dort hatte ich auch das Problem, dass nach .toprettyxml('encoding="utf-8"') die Umbrüche so dargestellt wurden. Ich hatte gehofft, dass es sich dabei um einen Fehler in der Methode handelt. Leider konnte ich im Netz keine guten Infos hierzu finden. Erreichen möchte ich, dass im Header der XML nicht nur die Version, sondern auch das encoding="" steht.


Beste Grüße

Jimyx
Zuletzt geändert von Anonymous am Mittwoch 4. September 2013, 14:01, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Der Code läuft bei mir einwandfrei (Anmerkung: ich verwende grundsätzlich Unicode-Strings).

Wofür soll eigentlich das t = str(t) gut sein?
Jimyx
User
Beiträge: 4
Registriert: Mittwoch 4. September 2013, 12:58

Hi,
bekommst du die Ausgabe in Pretty Print ?

Wenn ich das nicht in einen String wandel, meckert er bei file.write(t), dass er einen String und keinen Byte will.

Schön finde ich das aber auch nicht.

Beste Grüße

Jimyx
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Jimyx hat geschrieben:Wenn ich das nicht in einen String wandel, meckert er bei file.write(t), dass er einen String und keinen Byte will.
Welche Python-Version verwendest du?
Jimyx
User
Beiträge: 4
Registriert: Mittwoch 4. September 2013, 12:58

3.3
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Jimyx hat geschrieben:3.3
Tja, dann ist es klar. Lass die Umwandlung mit str weg und öffne stattdessen die Datei passend. Aktuell öffnest du sie mit "w" zum Schreiben im Textmodus, was du brauchst ist aber das Schreiben von Bytes mit "wb".
Jimyx
User
Beiträge: 4
Registriert: Mittwoch 4. September 2013, 12:58

Super du hast mir geholfen!

Nun wird alles richtig dargestellt.

Besten dank !
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Jimyx hat geschrieben:Nun wird alles richtig dargestellt.
Die Unterschiede zwischen Text (Unicode) und Byte sind ein langes Thema und es sind schon Massen an Entwicklern darüber gefallen.

Wichtig ist: Intern im Programm hast du (seit Python 3.0) Texte als Unicode-Objekte vorliegen. Unicode ist keine Zeichencodierung, Unicode ist erst einmal nur ein Konzept. Wenn die Daten nach außen (Speicher, Netz, ...) gehen sollen, dann müssen diese Texte codiert werden. Typischerweise nimmt man als Codierung UTF-8, aber es sind auch andere Codierungen wie ISO-8859-15 denkbar. Diese Umwandlung macht man entweder selber oder irgendeine API erledigt das für einen (wie hier lxml.etree._Element.tostring). Beim Einlesen von Daten muss man den umgekehrten Weg gehen.

Code: Alles auswählen

>>> 'Ärger'
'Ärger'
>>> 'Ärger'.encode('UTF-8')
b'\xc3\x84rger'
>>> b'\xc3\x9cbel'.decode('UTF-8')
'Übel'
Natürlich muss man zum Codieren und Decodieren die gleiche Codierung nehmen, sonst gibt's ... sieh selbst:

Code: Alles auswählen

>>> b'\xc3\x84rger'.decode('ISO-8859-1')
'Ã\x84rger'
Antworten