Seite 1 von 1

Unicode aus XML file umwandeln (minidom)

Verfasst: Montag 9. Juni 2008, 09:32
von martin.py
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ß

Verfasst: Montag 9. Juni 2008, 09:37
von Hyperion
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.

Verfasst: Montag 9. Juni 2008, 10:03
von 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.

Verfasst: Montag 9. Juni 2008, 12:55
von lunar
Dafür bräuchte man dann einen validierenden XML-Parser und ein passendes XML Schema, um die Typen der einzelnen Knoten zu definieren.

Verfasst: Montag 9. Juni 2008, 15:21
von martin.py
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ß

Verfasst: Montag 9. Juni 2008, 15:41
von Hyperion
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 ;-)

Verfasst: Montag 9. Juni 2008, 15:48
von martin.py
@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ß

Verfasst: Montag 9. Juni 2008, 16:07
von 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.

Verfasst: Dienstag 10. Juni 2008, 11:51
von martin.py
@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ß

Verfasst: Dienstag 10. Juni 2008, 12:02
von lunar
Suche in der Doku nach "lookahead assertion".

Verfasst: Dienstag 10. Juni 2008, 12:13
von martin.py
@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ß

Verfasst: Dienstag 10. Juni 2008, 12:35
von HWK
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

Verfasst: Dienstag 10. Juni 2008, 12:43
von martin.py
Ok, danke jetzt hab ichs kapiert. gruß