Seite 1 von 2

XML File gezielte Daten auslesen

Verfasst: Donnerstag 19. Juni 2008, 12:13
von Pü-Ton
Hallo Pythonianer,

ich weiss es gibt schon sehr viel Infos über XML und Python,
nur find ich nix, was meinen Vorstellungen entsrpicht...

Vielleicht hat ja einer von euch noch nen Link oder ein Beispiel für mich...

XML-file:

Code: Alles auswählen

<environment>
	<Informations>
		<Name>bla</Name>
		<Version>blub</Version>
		<Date>date</Date>
	</Informations>
	[color=red]<Variables>
		<Var>
			<Name>RestartMode</Name>
			<Value>Only necessary</Value>
		</Var>
		<Var>
			<Name>Languages_Order</Name>
			<Value>German</Value>
			<Options>;English;</Options>
		</Var>
		<Var>
			<Name>Path_Test</Name>
			<Value>T:\Testing\t</Value>
		</Var>
		
	</Variables>[/color]
	<Tests>
		<UserManagement>
			<Case>
				<Name>01_Show_Existing_Users</Name>
				<Selected>True</Selected>
				<Params></Params>
				<Comments>this is my comments</Comments>
			</Case>
		</UserManagement>
	</Tests>
</environment>

Ich will jetzt, dass mir nur Variables/Name ausgegeben wird, sonst nichts. Also soll als Ergebnis:

Code: Alles auswählen

RestartMode
Languages_Order
angezeigt werden.

Ich habe natürlich schon so manches rausgefunden und verwende nun Elementtree.

Hier mein Code:

Code: Alles auswählen

from xml.dom.minidom import*                    
from elementtree import ElementTree as et

files = file("C:\Python25\Test.xml", "r")
etree = et.parse(files)
files.close()
root_tag = etree.getroot()
files_tag = root_tag.find("Variables")
if files_tag:
    for file_tag in files_tag.findall("Var"):
        print file_tag.get("Name")
        print "  " + (file_tag.text or "")
und als Ergebnis kommt :

Code: Alles auswählen

None

None
Was fehlt da noch, dass ich an die Info komme

Verfasst: Donnerstag 19. Juni 2008, 12:36
von Hyperion
Denk noch mal über Zeile 12 nach ... "was macht das get() eigentlich?". Schau da noch mal in die Doku.

Verfasst: Donnerstag 19. Juni 2008, 12:49
von audax

Code: Alles auswählen

from xml.etree import ElementTree as et 

xml = et.parse(open('x.xml', 'r'))

variables = xml.find('Variables')
for elem in variables.findall('Var'):
    print elem.tag, elem.text

Verfasst: Donnerstag 19. Juni 2008, 13:12
von Pü-Ton
hmmm, also das funzt ja schon, nur bekomm ich nicht den Inhalt aus "Var" angezeigt,geschweigedenn den eingentlichen Inhalt von Name, also "RestartMode" und "Languages_Order" sondern:

Code: Alles auswählen

Var


Var
Ich müsste also noch eine Hirarchieebene weiter runter.

Code: Alles auswählen

<Variables>
        <Var>
            <Name>RestartMode</Name>
            <Value>Only necessary</Value>
        </Var>
        <Var>
            <Name>Languages_Order</Name>
            <Value>German</Value>
            <Options>;English;</Options>
        </Var>
        <Var>
            <Name>Path_Test</Name>
            <Value>T:\Testing\t</Value>
        </Var>
       
    </Variables>

Verfasst: Donnerstag 19. Juni 2008, 13:36
von Pü-Ton
Hab die Lösung gefunden und schreib sie hier rein, für alle, die mal an das gleiche Problem stossen:

Code: Alles auswählen

xml = et.parse(open("C:\...", 'r')) # hier den Pfad des XML-Files eingeben
variables = xml.find('Variables')  
for elems in variables.findall('Var'):
    var = elems
    for elem in var.findall("Name"):
        print elem.tag, elem.text
danke an alle Beteiligten

Verfasst: Freitag 20. Juni 2008, 11:20
von Daniela
Ich hab grad mal dein Skript ausprobiert, da ich ein ähnliches Problem wie aus dem ersten Post habe/hatte.

Jedenfalls wenn ich das Skript nach meinen Wünschen umbaue, was nur bei dem Punkt variables und nach was gesucht werden soll der Fall ist, bekomme ich als Ausgabe das irgendein Modul nicht gefunden wurde.

Hier mal mein Code:

Code: Alles auswählen

from xml.dom.minidom import*
from elementtree import ElementTree as et

xml = et.parse(open("C:\dateipfad\eigeneRM_3.rm", 'r')) # hier den Pfad des XML-Files eingeben
variables = xml.find('Stations')
for elems in variables.findall('Station'):
    var = elems
    for elem in var.findall("Point"):
        print elem.tag, elem.text
Jedenfalls bekomme ich in folgendes dann angezeigt:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\dateipfad\eigeneRM_3.rm", line 4, in <module>
    from elementtree import ElementTree as et
ImportError: No module named elementtree
Kann mir jemand bitte sagen, was ich falsch mache, oder was noch dazu geschrieben werden muss???
Ach ja, nicht wundern, wegen der "rm"-Datei. Das ist wirklich eine XML-Datei und kein Video ;-)


LG

Daniela

Verfasst: Freitag 20. Juni 2008, 11:55
von Hyperion

Code: Alles auswählen

from xml.dom.minidom import*
from elementtree import ElementTree as et
...
Wozu denn noch der minidom import?
Versuche einfach mal:

Code: Alles auswählen

from xml.etree import ElementTree
Wie es Audax ja auch schon gemacht hat ;-) Ich vermute dass Du Python 2.5 hast, wohingegen der Threadsteller wohl noch mit einer 2.4er arbeitet.

Ich hoffe das hilft :-)

Verfasst: Freitag 20. Juni 2008, 12:12
von Daniela
Ach echt :shock:
Wusst ich jetzt nicht.

Wenn ich die Zeile 2 lösche, dann bekomme ich aber dennoch den gleichen Hinweis, wie vorher nur das jetzt der Fehler nciht mehr in Zeile 4 ist, sondern in Zeile 3.

Ich werd mir jetz mal das von audax trotzdem nochmal genauer anschauen.

Aber danke für den Hinweis.

Verfasst: Freitag 20. Juni 2008, 12:30
von Hyperion
Dann sag doch mal bitte, welche Python-Version Du hast. ElementTree ist erst sei 2.5 dabei (laut meiner Doku). Wenn Du auch diese Version hast, dann sollte das von Audax klappen.

Wenn Du < 2.5 hast, musst Du das Paket erst nachinstallieren und dann ist ggf. der andere import der richtige.

Ob ein Paket verfügbar ist, testet man am besten per Konsole.

Verfasst: Freitag 20. Juni 2008, 13:13
von Daniela
Eigentlich hab ich Python 2.5

Und wenn ich das von audax nehme, kommt der gleiche Fehler.

Verfasst: Freitag 20. Juni 2008, 15:39
von BlackJack
Falls das mit dem Importieren dann irgend wann klappt, kann man die Schleife über die Stationen auch mit einem `findall()` machen:

Code: Alles auswählen

from xml.etree import ElementTree as etree

def main():
    doc = etree.parse('test.xml')
    result = list()
    for station in doc.findall('stations/station'):
        point = station.find('point')
        result.append((station.get('name'),
                      (int(point.get('x')), int(point.get('y')))))
    print result
Bei mir sind die Tags klein geschrieben, weil das in einem anderen Thema im Forum bei einem gegebenen Beispiel auch so war.

Verfasst: Freitag 20. Juni 2008, 18:54
von Hyperion
Daniela hat geschrieben:Eigentlich hab ich Python 2.5
Und uneigentlich? ;-) Starte doch mal in der Shell

Code: Alles auswählen

python -V
(Sofern python im PATH steht, ansonsten eben direkt die .exe aufrufen.) Unter Linux sollte Python eh im Pfad stehen.

Verfasst: Montag 23. Juni 2008, 07:11
von Daniela
auch uneigentlich hab ich Python 2.5.2!!!

Ich arbeite über windows! Windows XP, falls das wichtig ist?

Verfasst: Montag 23. Juni 2008, 10:28
von Hyperion
Kannst Du bitte noch einmal eine Konsolen-Session starten und die genaue Meldung per copy und paste hier reinstellen? So kommen wir nicht weiter ...

Verfasst: Montag 23. Juni 2008, 10:47
von Daniela
Keine Ahnung warum, aber wenn ich mein Skript jetzt ausführe, bekomme ich keine Fehlermeldung mehr, dass irgendein Modul nicht gefunden wurde.

Jedenfalls läuft es aber immer noch nicht so, wie ich es gern hätte. Bei meinem Code erhalte ich trotzdem immernoch ne Fehlermeldung, dass die Datei nicht gefunden wurde.

Code: Alles auswählen

from xml.etree import ElementTree as et

xml = et.parse(open("C:\Dokumente und Einstellungen\Benutzer\Dokumentenpfad\eigeneRM3.rm", 'r')) #allgemein gehalten
variables = xml.find('Stations')
for elems in variables.findall('Station'):
    var = elems
    for elem in var.findall("Point"):
        print elem.tag, elem.text
Ich muss aber noch dazu sagen, dass mein Dokumentenpfad etwas lang ist. Insgesamt erstreckt sich der Pfad auf 8 Unterordner. Ist das vielleicht zu viel???
Denn wenn ich es jetzt ausführe, dann bekomme ich folgendes:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\gast_82z\workspace\betoscan\src\MeanderMovement.py", line 3, in <module>
    xml = et.parse(open("C:\Dokumente und Einstellungen\Benutzer\Dokumentenpfad\eigeneRM3.rm", 'r')) # hier den Pfad des XML-Files eingeben
IOError: [Errno 2] No such file or directory: 'C:\\Dokumente und Einstellungen\\Benutzer\\Dokumentenpfad\\eigeneRM3.rm'
Es kann aber eigentlich nicht sein, da die Datei wirklich in dem von mir angegebenen Pfad liegt.

Ich wär ja schon mal froh, wenn die Datei gefunden wird und irgendeinen der abgespeicheten Werte ausliest, damit ich damit dann weiterarbeiten könnte. Wenigstens den ersten.

Daniela

Verfasst: Montag 23. Juni 2008, 11:01
von Hyperion
Hallo,

naja, Du wirst schon irgend etwas verändert haben ;-)

Zu den neuerlichen Problemen:

1.) Nutze Exceptions, Speziell beim Parsen sollte man einen IOError stets abfangen (oder ab Python 2.6 mit with arbeiten ...)

2.) Kopiere Die zu Parsende Datei einmal in das selbe Verzeichnis wie Dein Script und teste erst einmal, ob der Rest klappt.

3.) Baue Pfade immer per os.join() zusammen!

4.) Teste doch mal, ob die Datei dort wirklich liegt, mit os.listdir()

So solltest Du weiter kommen!

PS: Wieso eigentlich acht Unterverzeichnisse? Ich zähle vier!

Verfasst: Montag 23. Juni 2008, 11:23
von Daniela
die Punkte 1-4 werd ich mal ausprobieren

Zum ps:

ich hab den angegebenen Dateipfad gekürzt. Im Original sind es 8 unterverzeichnisse.
also

Code: Alles auswählen

C::\Dokumente und Einstellungen\Benutzer\Desktop\Projektordner1\projektordner2\Programm\Unterprogramm\Unterordner\Roadmap\eigeneRM3.rm
So sieht die eigentliche Ordnerstruktur aus.

Hab jetzt mal die XML-Datei in den Ordner kopiert, wo das Python-Skript liegt und es kommt wieder dieser IOError.

An sich will ich ja "nur" 4 Koordinaten-Punkte aus meiner XML-Datei rausgelesen haben. Damit ich mit diesen Punkten dann weiterarbeiten kann.

Hier mal die XML-Datei

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE roadmap SYSTEM "roadmap.dtd">
<roadmap version="1.2">
	<stations>
		<station id="id0" angle="0" name="Station1">
			<point x="-7962" y="4024" />
		</station>
		<station id="id1" angle="0" name="Station2">
			<point x="4098" y="3964" />
		</station>
		<station id="id2" angle="0" name="Station3">
			<point x="4120" y="-3062" />
		</station>
		<station id="id3" angle="0" name="Station4">
			<point x="-7903" y="-2903" />
		</station>
	</stations>
</roadmap>
Und da wär nicht schlecht die ID, und die beiden Koordinaten für x und y zu bekommen.

Verfasst: Montag 23. Juni 2008, 11:30
von BlackJack
War das jetzt der wirkliche Name des Ordners, oder hast Du etwas verändert? Du weisst, dass bestimmte Kombinationen von '\' + Buchstaben in literalen Zeichenketten als *ein* Byte interpretiert werden!? Zum Beispiel '\n' als Zeilenende, oder '\t' als Tabulatorzeichen.

Verfasst: Montag 23. Juni 2008, 11:34
von Hyperion
Daniela hat geschrieben: Hab jetzt mal die XML-Datei in den Ordner kopiert, wo das Python-Skript liegt und es kommt wieder dieser IOError.
Du hast natürlich die Pfadangabe entsprechend geändert?

Wieso eigentlich ignorierst Du die Lösung von BlackJack zu penetrant? Die funktioniert doch einwandfrei!

Und die Pfadangabe wird dann def. fehlerhaft sein! Eine andere Erklärung für den IO-Fehler gibt es nicht! (Davon abgesehen übernimmt das Öffnen sogar ElementTree - das open() kann man sich also sparen)

Mich beschleicht ein wenig die Annahme, dass Du nicht sauber arbeitest.

Verfasst: Montag 23. Juni 2008, 12:17
von Daniela
Also als ich die Datei in den gleichen Ordner kopiert hatte, hatte ich natürlich die Pfade auch geändert.

Warum ich die Lösung von BlackJack ignoriert habe???
Ganz einfach ich hab sie nicht gelesen bzw. überlesen und nicht wirklich für voll genommen.
Tut mir wirklich leid. :oops:

Aber ich hab es grad nachgeholt und wenn ich es über die Konsole aufrufe, bekomme ich keine Fehlermeldung oder ähnliches.
Das ist doch schonmal was!

Kann ich mir auch den Inhalt von result anschauen, um zu sehen, ob es der richtige ist?
Wenn ich hinter der Funktion "main()" aufrufe, werden mir (mal wieder) ein paar Fehler angezeigt.

Code: Alles auswählen

from xml.etree import ElementTree as etree

def main():
    doc = etree.parse('C:\Dokumente und Einstellungen\gast_82z\Desktop\Betoscan\betoscan\NeoPlatformControl\Platform\Roadmap\eigeneRM3.rm')
    result = list()
    for station in doc.findall('stations/station'):
        point = station.find('point')
        result.append((station.get('id'),
                      (int(point.get('x')), int(point.get('y')))))
    print result

main()
Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\gast_82z\workspace\betoscan\src\MeanderMovement.py", line 12, in <module>
    main()
  File "C:\Dokumente und Einstellungen\gast_82z\workspace\betoscan\src\MeanderMovement.py", line 4, in main
    doc = etree.parse('C:\Dokumente und Einstellungen\gast_82z\Desktop\Betoscan\betoscan\NeoPlatformControl\Platform\Roadmap\eigeneRM3.rm')
  File "C:\Python25\Lib\xml\etree\ElementTree.py", line 862, in parse
    tree.parse(source, parser)
  File "C:\Python25\Lib\xml\etree\ElementTree.py", line 579, in parse
    source = open(source, "rb")
IOError: [Errno 2] No such file or directory: 'C:\\Dokumente und Einstellungen\\gast_82z\\Desktop\\Betoscan\x08etoscan\\NeoPlatformControl\\Platform\\Roadmap\\eigeneRM3.rm'


Ohne die Zeile 12 (dem main-aufruf) läuft es problemlos durch. Nur wie bekomme ich dann wenigstens zur Kontrolle die ausgelesenen Werte angezeigt? Und wie kann ich später mit den Werten arbeiten.


Vielen Dank schon mal für eure Hilfe und vor allem eurer Gedult.

Daniela