Unicode aus XML file umwandeln (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.
Antworten
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

Hi, ich habe mir ein Python Skript geschrieben, dass Daten aus einer XML File ausliest und benutze dafür minidom. Nun bekomme ich die Daten als Unicode was natürlich nicht so optimal ist. Weiss jemand ob es in minidom ein feature gibt, dass die Daten in die jeweils passenden Python-Datentypen (bool, int, str, float) umwandeln kann oder hat sonst noch jemand ne idee ansonsten werd ich mir selbst was schreiben. gruß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also afaik gibt es da bei DOM keine Funktionalität, sondern man bekommt quasi alles als String geliefert, den man dann entsprechend konvertieren muss / kann.
BlackJack

@martin.py: Natürlich kommen die Daten als Unicode. Anders geht's doch auch gar nicht, weil ja nicht bekannt ist, was eine Zahl, Wahrheitswert usw. sein soll. Dazu muss man wissen was die Tags, Attribute, und Textknoten für eine Bedeutung haben.
lunar

Dafür bräuchte man dann einen validierenden XML-Parser und ein passendes XML Schema, um die Typen der einzelnen Knoten zu definieren.
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

Hi,
danke erstmal für die Antworten. Ich dachte daran, die Daten auf die gängigsten Datentypen zu überprüfen und demnach implizit zu casten. Dazu hab ich mir mal das regular Expression Modul angeschaut. Das ist dabei rausgekommen:

Code: Alles auswählen

zeichenExpr = re.compile('[+-]?\D+')
boolTrueExpr = re.compile('^(?i)true$')
boolFalseExpr = re.compile('^(?i)false$')
floatExpr = re.compile('^[+-]?(\d+\.\d*|\d*\.\d+)$')
intExpr = re.compile('^[+-]?\d+$')


if boolTrueExpr.match( dataIn ):
    dataOut = True
elif boolFalseExpr.match( dataIn ):
    dataOut = False
elif floatExpr.match( dataIn ):
    dataOut = float(dataIn)
elif intExpr.match( dataIn ):
    dataOut = int(dataIn)
else:
    dataOut = str(dataIn)
Im Internet hab ich noch nen ziemlich komplexen ausdruck für float gesehen:

Code: Alles auswählen

^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$
der deckt wirklich alles ab (was ich so getestet hab). Ich hab ihn auch fast nachvollzogen außer dem Ausdruck:

Code: Alles auswählen

(?=\d|\.\d)
Das (?=..) versteh ich nicht. Was bewirkt das genau? Ich kann mit der Beschreibung im Kodos leider nix anfangen.

Ich werd diesen Ausdruck wohl für float nehmen. Hat sonst noch jemand verbesserungsvorschläge?

gruß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wozu machst Du das eigentlich? Kannst Du uns den Anwendungsfall einmal genauer darlegen? Im Moment sehe ich in einem impliziten Casting irgend wie mehr Probleme als Vorteile. Aber ich kann da auch daneben liegen ;-)
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

@Hyperion: Ich will "tests" automatisieren. Die "tests" bestehen aus Commando-lines. Die Elemente der Commando-lines sind in XML-Files gespeichert und können Zahlen, Wörter oder irgendwelche Ausdrücke sein. Diese lese ich aus und gebe sie an bestehende Skripte (nicht von mir geschrieben) weiter. Wenn jemand nen neuen Test erzeugt, wäre es von Vorteil, wenn der Cast sofort nach dem Parsen passiert weil man es sonst leicht vergisst wenn man die Elemente dann verwerten will. Gruß
BlackJack

*Warum* wäre das von Vorteil? Und wiegt das die Nachteile auf? Zum Beispiel das auch Eingaben "gecastet" werden, die man gar nicht "gecastet" haben möchte! Der Codename von James Bond ist die Zeichenkette '007' und nicht die Zahl 7, ähnliches gilt bei Postleitzahlen und Telefonnummern. Oder die Monatsangabe '2008.06' wird plötzlich zur Fliesskommazahl 2008.0599999999999.
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

@BlackJack: Ok stimmt, an solche Daten hab ich nicht gedacht, weil bei der Hardware an der ich arbeite so was nicht relevant ist. Ich werd mein Skript trotzdem bei mir einbaun und damit is gut.

Kann mir jemand vielleicht noch bei dem dem "regular Expression"

Code: Alles auswählen

(?=...)
helfen und erklären was das bringt?

gruß
lunar

Suche in der Doku nach "lookahead assertion".
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

@lunar: danke, das steht in Kodos auch. "For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov' " das is nicht schwer zu verstehen. Was aber bedeutet "but doesn’t consume any of the string"? Heisst das dass der nachfolgende Regular Expression auch noch auf Asimov angewandt wird oder wie kann man das verstehen?

gruß
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ja!

Code: Alles auswählen

>>> re.match('Isaac (?=Asimov)', 'Isaac Asimov').group(0)
'Isaac '
>>> re.match('Isaac Asimov', 'Isaac Asimov').group(0)
'Isaac Asimov'
>>> re.match('Isaac (?=Asimov)Asimov', 'Isaac Asimov').group(0)
'Isaac Asimov'
>>> re.match('Isaac (?=Asimov)As', 'Isaac Asimov').group(0)
'Isaac As'
>>> re.match('Isaac Asimov As', 'Isaac Asimov')
MfG
HWK
martin.py
User
Beiträge: 10
Registriert: Sonntag 8. Juni 2008, 18:42

Ok, danke jetzt hab ichs kapiert. gruß
Antworten