ElementTree Problem mit Umlauten

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
Duesselentchen
User
Beiträge: 19
Registriert: Dienstag 15. März 2011, 17:08

Hallo liebe Forumsuser,

ich benutze Python 2.6 auf einem WindowsXP.

Was ich vorhabe:
Ich habe einen Ordner mit x XML-Dateien, welche ich alle einzeln parse (natürlich mit for... ;) ) und mir die XML-Dateien in einen anderen Ordner kopiere, wenn der Inhalt eines bestimmten Tags nicht meiner Konvertierung folgt.

Mein Problem:
Es funktioniert alles soweit so gut, bis das Programm auf eine XML-Datei stößt, welche Umlaute enthält. Jedoch steht im Header der einzelnen Dateien

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8" ?>
Fehlermeldung:
not well-formed (invalid token): line 11, column 19

Nun bin ich ehrlich gesagt so langsam mit meinem Latein am Ende. Wenn ich nach der Fehlermeldung google, heißt es dort, dass ich die Codierung auf UTF-8 ändern soll - aber laut XML-Header ist es doch schon UTF-8?! Auch habe ich schon mit

Code: Alles auswählen

.encode().decode()
ausprobiert und mal ein paar Standardcodierungen eingegeben - dies hat aber natürlich auch nicht geholfen.

Hat jemand eine Idee, wo mein Fehler liegen könnte?



Und hier noch ein Ausschnitt meines Codes:

Code: Alles auswählen

for datei in pfad:

    try:        
        tree = ElementTree.parse(Pfad+ "\\" + datei)
        tables = tree.getroot().getchildren()
    
        
        for leaf in tables:
            leafOrder = leaf[0].getchildren()
            
      
        for tag in leafOrder:
            singleTag = tag.tag
  
            if singleTag == 'No':
                
                if len(tag.text) > 8:
                    shutil.copy2(Pfad + "\\" + datei, AussortierteDateien)
                    
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Bist du sicher, dass die Datei auch im UTF-8-Format gespeichert wurde?
BlackJack

@Duesselentchen: Wenn im XML-Header als Kodierung UTF-8 steht, das parsen dann aber wegen einem Kodierungsfehler abbricht, dann ist die Datei offensichtlich nicht UTF-8-kodiert. Dann muss man sie entweder umkodieren, damit sie wirklich in UTF-8 vorliegt, oder man korrigiert die Information im XML-Header. In beiden Fällen muss man wissen wie die Datei tatsächlich kodiert ist.

Bezüglich der Namensgebung der Hinweis auf: PEP 8 -- Style Guide for Python Code.

Die Namen selbst sind abgesehen von der Formatierung teilweise schlecht gewählt. Man sollte sich entweder für Deutsch oder für Englisch entscheiden.

`pfad` scheint kein Pfad sondern eine Sequenz von Dateinamen zu sein. Verwirrend ist dann `Pfad` das subtil anders geschrieben wird und tatsächlich an einen Pfad gebunden ist. `datei` wird nicht an Dateien sondern an Datei*namen* gebunden. `leaf` ist nicht an ein Blatt gebunden, denn dann würde ein `getchildren()`-Aufruf darauf keinen Sinn machen. `tag` und `singleTag` scheinen auch die falschen Namen zu sein. Was man dort bekommt sind Knoten und die haben ein `tag`-Attribut. Wenn der Knoten in der Problemdomäne also kein Tag repräsentiert, sollte man ihn auch nicht so nennen. An dem Namen `AussortierteDateien` erkennt man nicht dass es sich um einen Pfad handelt.

Die Schleife über `tables` ist unnötige Laufzeitverschwendung. Wenn man eigentlich nur das letzte Element verarbeiten möchte, macht es keinen Sinn alle anderen auch zu verarbeiten, die Ergebnisse aber unbenutzt zu verwerfen.

Pfade sollte man mit `os.path.join()` zusammensetzen. Und wenn man das Ergebnis mehrfach braucht, sollte man es an einen Namen binden statt die Operation mehrfach durchführen zu lassen.
Duesselentchen
User
Beiträge: 19
Registriert: Dienstag 15. März 2011, 17:08

@/me: Jetzt wo du es schreibst - nein. Ich bin fälschlicherweise davon ausgegangen, weil es ja im Header steht.... Aber Danke für den Hinweis - jetzt weiß ich, wo ich weiter arbeiten kann!

@BlackJack: 1000 Dank für deine Mühe meinen Code auseinanderzunehmen! Der Punkt mit dem "Pfad" kam eigentlich nur, um den richtigen Pfad zu zensieren - der Rest ist aber wirklich eine unsaubere Benennung, Codierung etc. von mir. Das wärde ich nun schleunigst ändern!

Vielen Dank euch beiden!
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Duesselentchen hat geschrieben:@/me: Jetzt wo du es schreibst - nein. Ich bin fälschlicherweise davon ausgegangen, weil es ja im Header steht.... Aber Danke für den Hinweis - jetzt weiß ich, wo ich weiter arbeiten kann!
Man kann eventuell rumpfuschen, allerdings habe ich es nicht ausprobiert.

Code: Alles auswählen

botch_parser = etree.XMLParser(encoding='ISO-8859-1')
root_node = etree.parse(xml_file, parser=botch_parser).getroot()
Solltest du die Dateiquelle aber unter Kontrolle haben, dann wäre es um Längen besser die Dateien gleich richtig zu speichern.
Duesselentchen
User
Beiträge: 19
Registriert: Dienstag 15. März 2011, 17:08

Nach langem hin und her vermute ich UTF-16 als richtiges Encoding.

@BlackJack: leider stehen mir nur die Dateien zur Verfügung und kann an deren Erstellung nichts mehr groß ändern - aber das ist ja mal ein Grund, mit dem "Erzeuger" zu sprechen.
Deinen Code habe ich auprobiert, jedoch mit folgender Fehlermeldung:
__init__() got an unexpected keyword argument 'encoding'
BlackJack

@Duesselentchen: Ich nehme mal an /me ging von `lxml.etree` aus und nicht dem `ElementTree` aus der Standardbibliothek.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@Duesselentchen: Ich nehme mal an /me ging von `lxml.etree` aus und nicht dem `ElementTree` aus der Standardbibliothek.
Ich war nicht davon ausgegangen, dass jemand das ElementTree aus der Standardbibliothek nutzt ... :oops:
Duesselentchen
User
Beiträge: 19
Registriert: Dienstag 15. März 2011, 17:08

Okay - die "Erzeuger" schauen mal, was sie für mich tun können. Es ist mir selbst auch lieber, dass die Dateien direkt in Ordnung sind und ich nicht nachträglich etwas ändern muss.

Nun aber eine Frage hierzu:
Ich war nicht davon ausgegangen, dass jemand das ElementTree aus der Standardbibliothek nutzt ... :oops:
Ist nun ElementTree 'schlechter' als lxml.etree?
Da mein Script später auf dem Server laufen soll, kann / darf ich keine neuen Module installieren - lediglich importieren.
BlackJack

@Duesselentchen: Ich würde es nicht unbedingt in besser/schlechter ausdrücken, aber `lxml` kann einfach mehr. Zum Beispiel die Kodierung beim Parser angeben und für mich das Killerargument: XPath und CSS-Selektoren.
Antworten