Python string,dict,list und Co. <-> XML

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.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 07:45

Gerade bei "Daily Python-URL" gesehen:
http://cheeseshop.python.org/pypi/pyfo

Kann aus x-beliebig verschachtelten dicts und listen XML erzeugen... Leider aber nicht anders herrum :( Das wäre aber ideal für Fälle in dem man normalerweise Pickle nehmen könnte...

Kennt jemand auch ein kleines Modul, welches in beiden Richtungen Funktioniert???

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 15. März 2006, 08:25

jens hat geschrieben:Kennt jemand auch ein kleines Modul, welches in beiden Richtungen Funktioniert???
Hi Jens!

Ich habe XMarshaL für solche Fälle im Einsatz. Es ist aber nicht unbedingt ein *kleines* Modul, da es auch von pyXML abhängt. Aber es erfüllt seinen Zweck.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 08:41

gerold hat geschrieben:XMarshaL
Funktioniert bei mir spontan nicht:
File "D:\temp\XMarshaL-0.46\XMarshaL.py", line 40, in ?
from xml.sax import saxlib, saxexts
ImportError: cannot import name saxlib
Braucht man noch ein zusätzliches Modul? Das hier: http://pyxml.sourceforge.net ?
OK, das wäre wirklich etwas sehr groß :(

EDIT: Das was ich suche ist wohl xml.pickle aus http://freshmeat.net/projects/gnosisxml/ Allerdings ist das auch sehr groß :(

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 15. März 2006, 09:08

jens hat geschrieben:Das hier: http://pyxml.sourceforge.net ?
OK, das wäre wirklich etwas sehr groß :(
Hi Jens!

Ja, man braucht dazu pyXML. Aber ich kenne keine akzeptable Alternative, wenn man auf XML angewiesen ist.

Meine persönliche Alternative zu XML ist YAML. Dafür verwende ich PySyck. Leider ist der Server für "Syck" die letzten Tage nicht erreichbar.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 09:19

Eine andere Alternativen ist xmlrpclib aus den built-ins... Aber es produziert nicht wirklich XML, aber irgendwie was ähnliches:

Code: Alles auswählen

import xmlrpclib

t = [
  {'status':'GM', 'rating':2700},
  {'status':'Computer', 'rating':2700},
  {'status':'Amateur', 'rating':1400},
]


dump = xmlrpclib.dumps(tuple(t))
print dump

load = xmlrpclib.loads(dump)[0]
for item in load:
    print item
Ausgabe:
<params>
<param>
<value><struct>
<member>
<name>status</name>
<value><string>GM</string></value>
</member>
<member>
<name>rating</name>
<value><int>2700</int></value>
</member>
</struct></value>
</param>
<param>
<value><struct>
<member>
<name>status</name>
<value><string>Computer</string></value>
</member>
<member>
<name>rating</name>
<value><int>2700</int></value>
</member>
</struct></value>
</param>
<param>
<value><struct>
<member>
<name>status</name>
<value><string>Amateur</string></value>
</member>
<member>
<name>rating</name>
<value><int>1400</int></value>
</member>
</struct></value>
</param>
</params>

{'status': 'GM', 'rating': 2700}
{'status': 'Computer', 'rating': 2700}
{'status': 'Amateur', 'rating': 1400}
Das hab ich auf http://www-128.ibm.com/developerworks/l ... ers23.html gefunden...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 09:45

gerold hat geschrieben:Meine persönliche Alternative zu XML ist YAML. Dafür verwende ich PySyck. Leider ist der Server für "Syck" die letzten Tage nicht erreichbar.
Während PySyck auf Syck als binarie aufsetzt ist http://pyyaml.org/wiki/PyYAML vielleicht das richtige für mich... Es ist YAML in pure Python. Allerdings wohl noch in der Entwicklung... Leider funktioniert gerade der SVN checkout nicht :(

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 15. März 2006, 09:48

jens hat geschrieben:Eine andere Alternativen ist xmlrpclib aus den built-ins...
Hi Jens!

Sieht wirklich nicht schlecht aus. Allerdings weiß ich jetzt auch, warum XMLRPC bei großen Datenmengen so langsam ist. Der Overhead ist enorm. Ich verstehe nicht, warum die Entwickler von XMLRPC keine kürzeren Namen verwendet haben. :?

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 15. März 2006, 10:06

jens hat geschrieben:http://pyyaml.org/wiki/PyYAML vielleicht das richtige für mich... Es ist YAML in pure Python. Allerdings wohl noch in der Entwicklung... Leider funktioniert gerade der SVN checkout nicht :(
Hi Jens!

Danke für den Hinweis. PyYAML 3000 kannte ich noch nicht. Allerdings kenne ich dessen Vorgänger zu genüge.

PyYAML (nennt sich jetzt anscheinend PyYAMLLegacy) hätte mich fast ein Projekt gekostet. PyYAML war so mit Fehlern vollgestopft, dass mich das Ausbügeln dieser Fehler einige Tage kostete. Als ich schon fast auf XML umsteigen wollte, bin ich auf PySyck gestoßen. Seitdem läuft alles wie am Schnürchen. Auch PySyck hatte mal Probleme, aber diese sind längst ausgebessert und seit dem läuft PySyck richtig gut.

Der Vorteil einer kleinen Lösung ohne große Abhängigkeiten ist aber nicht von der Hand zu weisen. Bitte lass uns wissen, wie sich PyYAML 3000 geschlagen hat, falls du es testest.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 10:19

gerold hat geschrieben:Bitte lass uns wissen, wie sich PyYAML 3000 geschlagen hat, falls du es testest.
Kann ich nicht, weil ich nicht an die Sourcen komme: http://pyyaml.org/ticket/1

Und ich hab keine Lust die Dateien per Hand aus Trac zu kopieren...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 15. März 2006, 13:11

SVN geht wieder...

Anscheinend geht es mit YAML3000 aber nur in einer Richtung... Von YAML -> Python, aber nicht anders herrum. Zumindest hab ich keine dump-Methode gefunden und das ist wohl mit There in no YAML emitter yet. gemeint, was?

Ansonsten geht es:

Code: Alles auswählen

import time

start_time = time.time()
import yaml

data = """
 - YAML
 - is
 - fun!
 - dict1:
    key1: 1
    key2: 2
    key3: 3
 - dict2:
    eins: value1
    zwei: value2
    drei: value3
"""

data = yaml.load_document(data)
duration = time.time() - start_time

print data
print duration
Ausgabe:
['YAML', 'is', 'fun!', {'dict1': {'key3': 3, 'key2': 2, 'key1': 1}}, {'dict2': {'drei': 'value3', 'eins': 'value1', 'zwei': 'value2'}}]
0.0929999351501

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Mittwoch 15. März 2006, 22:19

gerold hat geschrieben:Ich verstehe nicht, warum die Entwickler von XMLRPC keine kürzeren Namen verwendet haben.
Die Namen sind doch okay!? Kurz und beschreiben ganz gut worum es geht.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 16. März 2006, 07:28

Ich denke gerold meint wohl ehr, die vielen zusätzlichen, leeren Namen... Ist schon ganz schön aufgebläht...

Hier mal ein gegenvorschlagt, wie sowas aussehen kann:

Code: Alles auswählen

t = [
    "beispiel", 123, "noch was",
    {'status':'GM', 'rating':2700},
    {'status':'Computer', 'rating':2700},
    {'status':'Amateur', 'rating':1400},
    {
        "eins": {"a":1, "b":2},
        "zwei": {"c":2, "d":3},
    },
]


<list>
    <string>beispiel</string>
    <int>123</int>
    <string>noch was</string>
    <dict>
        <string key="status">GM</string>
        <int key="rating">2700</int>
    </dict>
    <dict>
        <string key="status">Computer</string>
        <int key="rating">2700</int>
    </dict>
    <dict>
        <string key="status">Amateur</string>
        <int key="rating">1400</int>
    </dict>
    <dict>
        <dict key="eins">
            <dict>
                <int key="a">1</int>
                <int key="b">2</int>
            </dict>
        </dict>
        <dict key="zwei">
            <dict>
                <int key="c">2</int>
                <int key="d">3</int>
            </dict>
        </dict>
    </dict>
</list>
Wobei mir jetzt schon auffällt, das ein Key in einem dict, nicht mit einem Typen angegeben ist...

Aber ich kann nicht wirklich glauben, das es nicht schon sowas in der Art, irgendwo fertig rumschwirrt...

EDIT: btw. pyfo kann man vergessen, funktioniert nicht wirklich gut :(

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 16. März 2006, 09:24

Hi!

XMLRPC muss ja nicht menschenlesbar sein. Es dient dem Übertragen von Daten von einem Programm zum anderen oder von einem Computer zum anderen. Ich wäre in diesem Fall sogar noch weiter als Jens gegangen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xmlrpclib

tags = (
    ("param", "p"),
    ("value", "v"),
    ("struct", "d"),
    ("member", "m"),
    ("name", "n"),
    ("int", "i"),
    ("string", "s"),
    ("double", "f"),
    ("data", "dat"),
)

def verkleinern(xml):
    for old, new in tags:
        xml = xml.replace("<%s>" % old, "<%s>" % new)
        xml = xml.replace("</%s>" % old, "</%s>" % new)
    return xml

def vergroessern(xml):
    for new, old in tags:
        xml = xml.replace("<%s>" % old, "<%s>" % new)
        xml = xml.replace("</%s>" % old, "</%s>" % new)
    return xml

t = (
    {"Vorname": "Martin", "Nachname": "Thompson", "Alter": 10},
    {"Vorname": "Maria", "Nachname": "Thompson", "Alter": 11},
    {"Vorname": "Mustermann", "Nachname": "Thompson", "Alter": 12.5},
    {"Vorname": "Manuela", "Nachname": "Schuepfli", "Alter": 13.6},
    {"Vorname": "Kartoffel", "Nachname": "Puffer", "Alter": 14},
    {"Vorname": "Sagenhaft", "Nachname": "Imbett", "Alter": 30},
)

dumpgross = xmlrpclib.dumps(tuple(t))
dumpklein = verkleinern(dumpgross)

len_dumpgross = len(dumpgross)
len_dumpklein = len(dumpklein)
len_eingespart = len_dumpgross - len_dumpklein
print "Vorher:     %10i Byte  100.00%%" % len_dumpgross
print "Nachher:    %10i Byte  %6.2f%%" % (
    len_dumpklein,
    (100.0 / len_dumpgross * len_dumpklein)
)
print "Eingespart: %10i Byte  %6.2f%%" % (
    len_eingespart, 
    (100.0 / len_dumpgross * len_eingespart)
)

dumpgross = vergroessern(dumpklein)
load = xmlrpclib.loads(dumpgross)[0]

Code: Alles auswählen

Vorher:           1716 Byte  100.00%
Nachher:           972 Byte   56.64%
Eingespart:        744 Byte   43.36%
Das fürfte das Datenaufkommen bei Datenbankabfragen erheblich vermindern und dadurch beschleunigen.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 16. März 2006, 09:45

gerold hat geschrieben:XMLRPC muss ja nicht menschenlesbar sein. Es dient dem Übertragen von Daten von einem Programm zum anderen oder von einem Computer zum anderen.
Naja, mir geht es aber darum, das es Menschenlesbar ist... Halt im Prinzip der YAML Ansatz, nur halt in XML... z.B. für Config-Dateien, wo man nicht immer INI nehmen kann, weil es zu komplex wird...

Und mit XMLRPC ist es nicht wirklich lesbar, ob nun in der Original Version, oder in deiner "komprimierten" variante. Das liegt zum einen an dem fehlenden Einrückung und zum anderen in den unoptimalem Aufbau. Der ist wahrscheinlich dazu da, mehr als nur Strings, Dicts, Listen usw. unterzubringen, was?

Wenn man es nur zur kommunikation zwischen Programmen braucht, frag ich mich, warum man dann nicht besser pickle nimmt (zumindest, wenn auf beiden Seiten Python ist)...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 16. März 2006, 23:07

Ich werf jetzt noch neben YAML auch noch JSON rein, zusammen mit JSON-RPC ;)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten