XML Import/Export

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
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

Montag 23. April 2007, 10:29

Hi!

Wie kann ich mit Python eine XML Import-/Exportieren?
Gibt es da Libs und HowTo dazu?

ZB. hab ich folgendes XML File

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<book>
<name>The Book Title</name>
<genre>Science Fiction</genre>
<isbn>12345</isbn>
<author1>Homer Simpson</author1>
<author2>Douglas Heffernan</author2>
<pages>348</pages>
</book>
Nun sollen die taginhalte in lokale gleichnamige valiabeln 'umgeschrieben' werden.

also: <name>The Book Title</name> -> name = "The Book Title"

beim export sollen dann die variabeln wieder in deine xml geschrieben werden nach dem gleichen prinzip.

also gibt es da eine möglichkeit zu?
BlackJack

Montag 23. April 2007, 11:01

Die Formulierung klingt ein bisschen nach Hausaufgabe.

In lokale Variablen kann man das nicht umwandeln, das wäre auch ein bisschen sinnlos oder gefährlich. Ein Dictionary wäre eine geeignete Datenstruktur für Name/Wert-Paare, allerdings erhält das nicht die Reihenfolge der Namen, was bei XML fast immer wichtig ist.

Zum Einlesen und Schreiben von XML würde ich das ElementTree-Paket empfehlen. Das ist ab Python 2.5 in der Standardbibliothek enthalten, kann bei älteren Versionen aber zusätzlich installiert werden.
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

Montag 23. April 2007, 13:28

BlackJack hat geschrieben:Die Formulierung klingt ein bisschen nach Hausaufgabe.

Zum Einlesen und Schreiben von XML würde ich das ElementTree-Paket empfehlen. Das ist ab Python 2.5 in der Standardbibliothek enthalten, kann bei älteren Versionen aber zusätzlich installiert werden.
nö, ist keine hausaufgabe... but anyway

ich hab python 2.5 und hab element tree nicht gefunden
also hab ich runtergeladen und per
import elementtree.ElementTree as ET
importiert

ist aber soweit genau das was ich gesucht habe! THX!

nur noch zwei fragen dazu:

wenn ich beim einlesen checken will, ob der root korrekt ist (->book), mach ich das mit

tree = ET.parse("file.xml")
root = tree.getroot()
if root == "book":
......usw.....

aber dann krieg ich so was wie "<Element book at 1ab5300>" für root.
wie kann ich jetzt explizit auf "book" checken? oder muss ich da mit regex nachhelfen?

und die zweite frage hat mit dem export von int zu tun. wenn ich folgendes mache:

isbnnr = 12345
root = ET.Element("book")
isbn = ET.SubElement(head, "isbn")
isbn.text = isbnnr

geht das nicht. akzeptiert wohl nur strings. also mach ich
isbnnr = str(isbnnr)

find ich aber irgendwie unschön, weil ich nach dem export den wert dann wieder in int umwandeln muss, damit der rest des codes isbnnr versteht...
also gibts da keine bessere lösung um einen int auch als text zu exportieren?
BlackJack

Montag 23. April 2007, 15:24

Der XML-Tag-Name steckt im `tag`-Attribut:

Code: Alles auswählen

In [75]: root.tag
Out[75]: 'book'
XML kennt nur Zeichenketten, also musst Du explizit umwandeln. Allerdings würde ich das bei ISBN-Nummern nicht machen, das sind nämlich keine Zahlen. Zum einen rechnet man nicht damit und zum anderen kann die Prüf"ziffer" auch ein 'X' sein, solche Nummern lassen sich also nicht einfach in Zahlen umwandeln.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 23. April 2007, 21:31

Leicht ersichtlich steht auf der ET-Website:

Code: Alles auswählen

# import individual components
from elementtree.ElementTree import Element, ElementTree
from cElementTree import Element, ElementTree
from lxml.etree import Element, ElementTree
from xml.etree.ElementTree import Element, ElementTree # python 2.5     <------------

# import main module under an alias
import elementtree.ElementTree as ET
import cElementTree as ET
import lxml.etree as ET
import xml.etree.ElementTree as ET # python 2.5     <------------
[/quote]
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

Donnerstag 26. April 2007, 07:24

@BlackJack
danke für den tag!

und was die isbn angeht: sagen wir einfach mal ich hab einen anderen wert zb preis, womit ich später mal noch rechnen will. geht dann ja wohl auch nicht anders als den wert von int -> str und danach wieder str -> int, oder?

@YOGi
danke, das hab ich wohl irgendwie übersehen. machmal muss man wohl zu seinem glück gezwungen werden ;p!

Code: Alles auswählen

        root = ET.Element("book")            
            name = ET.SubElement(root, "name")
            name.text = self.name
            
            genre = ET.SubElement(root, "genre")
            genre.text = self.genre 
        
        tree = ET.ElementTree(root)
        tree.write("C:/my/path/book.xml", "UTF-8")
dieser code erzeugt eigentlich eine xml wie ich sie haben will. nur leider alles in einem string. dh. 1 zeile = <?xml tag 2. zeile = der ganze rest
gibt es einen befehl, damit das ganze gestaffelt schön nach xml in das file geschrieben wird? eben newlines und so...

ps: wenn ihr ne page kennt, wo die ET befehle gut veranschaulicht werden, wär ich dankbar. hab bisher noch keine passende gefunden..
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 26. April 2007, 07:57

BaseBallBatBoy hat geschrieben:dieser code erzeugt eigentlich eine xml wie ich sie haben will. nur leider alles in einem string.
Hallo BBBB!

Vielleicht kannst du mit diesem Thread etwas anfangen.
http://www.python-forum.de/topic-8687.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

Montag 30. April 2007, 11:17

jo, das konnte ich! indent macht genau was ich will. finds nur komisch, dass so was nicht bereits automatisch gemacht wird...

hab nun noch ne frage, wie ich den inhalt eines tags abspeichern kann
eg. <tag>inhalt</tag> -> self.tag = "inhalt"

ich mach folgendes:

Code: Alles auswählen

tree = ET.parse(XmlFilePath)
        
        root = tree.getroot()
                
        if root.tag == "book":
            if tree.findtext("erstesBuch"):
                if tree.getiterator("name"):
                    self.name = tree.findtext("name")
                    ....
also bei mir findet python auch "name" im xmlfile, aber das überschreiben der variable misslingt (None). ich geh also mal davon aus, dass tree.findtext nicht dazu gedacht ist inhalte aus einem tag zu hohlen...
also, kennt ihr den richtigen tag?

thx in adv
BlackJack

Montag 30. April 2007, 12:23

Automatisch einrücken kann man XML nicht so ohne weiteres. Dazu müsste man mehr über die Struktur und die erlaubten Inhalte von Tags wissen.

Die `findtext()` Methode sucht ein Tag, dessen Namen man angibt und gibt dessen Textinhalt zurück. Darum kommt mir Dein Quelltext etwas komisch vor. Oder hast Du tatsächlich ein Tag mit dem Namen 'erstesBuch'? Das wäre genau wie 'author1', 'author2' usw. im Beispiel im ersten Beitrag ein schlechter Entwurf. In Tagnamen gehören keine "variablen" Teile. Wenn mehrere Bücher in einem Dokument gespeichert werden sollen, nennt man das Wurzel-Tag 'books' und für jedes Buch kommt ein 'book'-Knoten vor. Genau so kann man mit mehreren Autoren verfahren: Einfach soviele 'author'-Tags angeben, wie das Buch Autoren hat.
Antworten