XML-Datei enthält Sonderzeichen.

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
Yierith
User
Beiträge: 3
Registriert: Donnerstag 26. Februar 2015, 07:09

Guten morgen,

habe ein kleines Problem.
Habe ettliche XML-Dateien mit xml.dom.minidom verarbeitet.
ex.:

Code: Alles auswählen

dom = xml.minidom.parse(xmlFile)

def dokument(dom):
	global value
	for node in dom.childNodes:
		inh = node.nodeName
		if node.nodeType == node.TEXT_NODE:
		    value = node.nodeValue.strip()
		    dokument(node)

                if node.nodeName.capitalize() == 'Warenempf':
			warenempfaenger = value
			print 'Hier ist ein Warenempfaenger!!!!!!!'

dokument(dom)
Das ging eine Zeit lang auch top. Bis "&" und "<, >, ' " auftauchten z.b. bei ' & Co. KG'.

Code: Alles auswählen

xml.parsers.expat.ExpatError: not well-formed (invalid token):
Gibt es einen Weg diese Sonderzeichen bevor ich sie verarbeite raus zu filtern bzw gänzlich aus der XML-Datei da sie für mich
eh nicht relevant sind zu entfernen? Habe viele Einträge gefunden in denen Ansättze sind, allerdings keiner der mir gerade weiterhilft..
Mein erster Ansatz wäre das öffnen der Datei und .replace zu nutzen, allerdings kenne ich keinen eleganten Weg...
Und die XML-Datei als Text-Datei zu behandeln ist auch nicht dir feine englische -.-
Hoffe das war so verständlich :/

Beste Grüße
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Yierith: das Problem ist, dass Du keine XML-Datei hast, sondern eine kaputte XML-Datei. Die richtige Lösung wäre, demjenigen, der die nicht-XML-Dateien erzeugt auf die Finger zu klopfen.
Zweitens hat minidom eine wirklich schreckliche API. Die schönere API hat ElementTree. Dann gäbe aus auch den Not-Behelf, mit lxml.html die Datei zu lesen. HTML ist im Umgang mit Fehlern toleranter, hat aber die gleiche Baumstruktur wie XML.
3. verwende niemals "global" vor allem nicht bei rekursiven Funktionsaufrufen. Du hast keine Kontrolle mehr darüber, wann der Wert geändert wird, was Debugging so sehr schwierig macht. Variablen kommen in eine Funktion über ihre Argumente und verlassen sie als Rückgabewert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also als erstes vergiss mindom! Nutze die ElementTree-API!

Kannst Du uns mal eine kleine Beispiel XML-Datei posten, bei der das Problem auftritt? Vermutlich ist das kein valides XML... ds zu reparieren ist vermutlich nicht so einfach...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Yierith
User
Beiträge: 3
Registriert: Donnerstag 26. Februar 2015, 07:09

Guten Morgen und danke für die schnelle Antwort ihr zwei,

@Sirius3 - Du hast recht was das auf die Finger Klopfen angeht. Allerdings wird mir die "kaputte XML-Datei" direkt aus SAP zugespielt. Bzw gibt es zu viele Daten die schon so erstellt sind, da das exportieren der XML-Datei erst seit kurzem Bestandteil dieses Schrittes ist, was es ist nicht einfach macht zu klopfen -.-

@Hyperion & Sirius3 - Ihr habt recht in der Annahme das die gelieferte Datei eine NICHT Valide XML-Datei ist. Ich dächte aber eventuell das ich ein
Script vorschalten könnte welches sich diese Datei abgreift, die 'nicht' Validen Zeichen aus dieser Datei entfernt, um am Ende eine Valide zu erhalten und weiter verarbeiten zu können. Dafür müsste ich diese XML aber Zeile für Zeile einlesen und auf diese Art von 'nicht' Valide Zeichen durchsuchen und sie womöglich ersetzen oder gar entfernen, da sie wie gesagt für mich keine Relevanz haben. Ob nun xxx & Co. KG oder xxx Co. KG, das macht bei weiteren Vorgängen keinen Unterschied
da ich diese Werte nicht weiter verwende.

@Hyperion - Hier mal ein snippet der XML wo es zu Problemen kommt.

Code: Alles auswählen

<?xml version="1.0" encoding="ISO-8859-1"?>
<auftrag>
  <status>
    <auftragsstatus>NeuerAuftrag</auftragsstatus>
  </status>
  <kopf>
  <warenempf>Max Mustermann GmbH & Co. KG</warenempf>
  </kopf>
</auftrag>
@Hyperion - Das & wirft alles übern Haufen, hoffe du kannst damit was anfangen.
BlackJack

@Yierith: Das Problem ist das diese Zeichen ja nicht an jeder Stelle im Dokument falsch sind, was letztendlich darauf hinaus läuft das man einen Parser braucht der etwas verarbeitet was so ähnlich wie XML ist um daraus etwas zu machen das ein XML-Parser verarbeiten kann.

Je nach Stand den man so in der Firma hat, würde ich mich da vielleicht echt auf die Hinterbeine stellen und Richtung Ersteller knurren und sagen das die Daten die da alle produziert wurden kaputt und damit wertlos sind weil kein Werkzeug das XML erwartet diese Daten lesen wird. Und das reparieren ist gefrickel was nicht robust ist. Genau um so etwas zu vermeiden gibt es ja XML (und andere Standards) für die man sich keinen eigenen Parser bauen muss. Ohne ein bisschen Druck lernen die Leute die denken XML sei Text und das kann man mit Textwerkzeugen erstellen (und verarbeiten) es offenbar nicht.

Edit: Für eine praktische Lösung würde ich wahrscheinlich `lxml` nehmen das solange parsen und auf die Ausnahmen für illegale Token reagieren (da ist die Position enthalten) und die einzeln ”reparieren”.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nimm die Hinweise ernst und versuche das Problem an der Quelle abzustellen. Das ist die beste Lösung und geht zu einem frühen Zeitpunkt auch noch recht einfach. Hinzu kommt natürlich, dass du dich ein wenig absichern kannst und dir am Ende niemand vorwirft, warum du da irgendwas zusammengefrickelt hast, was auf viel zu wackeligen Beinen steht. Das "Schöne" bei solchen Sachen ist nämlich, dass am Anfang das Umschiffen des Problems noch einfach aussieht. Dann wird es immer komplexer und unerwartete Fälle treten auf. Irgendwann fliegt einem das Ding dann um die Ohren. Und das spannende ist: Man weiß nie wie das passiert, wann es eintritt und wie teuer das am Ende wird ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wo wir gerade dabei sind... ``encoding="ISO-8859-1"`` ist für mich immer schon ein Zeichen, dass da etwas schräg ist! Wieso zum Geier kann der Erzeuger nur ISO-8859-1 liefern und kein UTF-8? Das ist imho häufig ein Indiz, dass der Erzeuger *wenig* Ahnung hat und sich mit dem Encoding von Strings nicht auskennt und einfach mal das Encoding angibt, "mit dem es unter Windows keine Probleme mit Sonderzeichen gibt". Und das lässt dann vermuten, dass er das XML per Hand zusammenklöppelt, wodurch es zu solchen Fehlern wie illegalen Zeichen kommt... :evil:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

In dem Zusammenhang ein Text dem man solchen Leuten ans Herz legen kann: HOWTO Avoid Being Called a Bozo When Producing XML.
Antworten