Hi XT@ngel,
Es sollte klappen, wenn du in deiner, von str abgeleiteten Klasse eine Methode to_xml definierst, die dann das Ausgeben als xml erledigt. Schau dir dazu das Beispiel im 2 mit der Base64-Stringklasse an ->
http://www.boa3d.de/python/modules/PyXO_Base64.py
Es gibt auch eine Klasse PyXO.CData.
Gruß
Dookie
XML_Objects - Tester und Kritiker gesucht
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Hi Dookie
Kannst du noch ein Beispiel machen in dem es verschachtelte Objects hat?
Mein Ziel ist es einen Baum zu speichern, jedoch hab ich es noch nicht geschafft, dass er die Container im Container richtig speichert.
Hier mal mein kleines Beispiel mit dem Problem:
Von diesen Elementen sollen nicht alle gespeichert werden, z.B. parent, name würde ich gerne als Attribut speichern (hab ich mit xml_attrs = {'parent':str, 'name':str}.
Jetzt sollen aber die Options, welches ein Dict ist, als unterelemente gespeichert werden und die childs sind auch wieder cWidgets.
Hoffe das hat man nun verstanden
. Wie bekomm ich ca. so eine XML-Struktur?
Gruss und schöne Weihnachten
Kannst du noch ein Beispiel machen in dem es verschachtelte Objects hat?
Mein Ziel ist es einen Baum zu speichern, jedoch hab ich es noch nicht geschafft, dass er die Container im Container richtig speichert.
Hier mal mein kleines Beispiel mit dem Problem:
Code: Alles auswählen
class cWidget(PyXO.Object):
__slots__ = ['parent','name','events','widgetClass','options','widget',
'childs','tree']
Jetzt sollen aber die Options, welches ein Dict ist, als unterelemente gespeichert werden und die childs sind auch wieder cWidgets.
Code: Alles auswählen
<cWidget name="..." parent="...">
<dict name="options">
</dict>
<childs>
<cWidget name="..." parent="...">
...
</cWidget>
</childs>
</cWidget>

Gruss und schöne Weihnachten
Hi,
ich hab das mit den Unterelementen so gelöst.
ich weiss nicht ob sich Dookie die Verwendung so vorgestellt hat.
MfG
Andreas
ich hab das mit den Unterelementen so gelöst.
ich weiss nicht ob sich Dookie die Verwendung so vorgestellt hat.
Code: Alles auswählen
#!d:/Program Files/Python23/python.exe -u
#-*- coding: Latin-1 -*-"
import PyXO
import os, sys, re
class Title(PyXO.Object):
__slots__ = ["Value"]
def __init__(self, Value, **kw):
super(Title, self).__init__(**kw)
self.Value = Value
self.xml_write_python_module
def __str__(self):
return self.Value[0]
class CreationDate(PyXO.Object):
__slots__ = ["Value"]
def __init__(self, Value, **kw):
super(CreationDate, self).__init__(**kw)
self.Value = Value
self.xml_write_python_module
def __str__(self):
return self.Value[0]
class Language(PyXO.Object):
__slots__ = ["Value"]
def __init__(self, Value, **kw):
super(Language, self).__init__(**kw)
self.Value = Value
self.xml_write_python_module
def __str__(self):
return self.Value[0]
class DocumentMeta(PyXO.Container):
__slots__ = ["Title",
"CreationDate",
"Language"]
def __init__(self, *args, **kw):
self.name = "DocumentMeta"
super(DocumentMeta, self).__init__(**kw)
if args:
self.Title = args[0][0]
self.CreationDate = args[0][1]
self.Language = args[0][2]
else:
pass
def to_xml(self, indent=0, indstr=PyXO.indstr, stream=None):
snip = """<DocumentMeta>
<Title>%s</Title>
<CreationDate>%s</CreationDate>
<Language>%s</Language>
</DocumentMeta>""" % (self.Title, self.CreationDate, self.Language)
if stream is not None:
stream.write(snip)
else:
return snip
class Chapter(PyXO.Container):
__slots__ = {"Nr": int ,
"Title": str
}
def __init__(self, *args, **kw):
super(Chapter, self).__init__(**kw)
self.name = "Chapter"
print args
if kw.has_key("Nr"):
self.Nr = kw.pop("Nr")
else:
self.Nr = args[0]
if kw.has_key("Title"):
self.Title= kw.pop("Title")
else:
self.Title = args[1]
def GetContent(self):
pass
class PyBook(PyXO.Root):
__slots__ = ["DocumentMeta", "Chapter"]
def __init__(self, *args, **kw):
super(PyBook, self).__init__(*args, **kw)
self.DocumentMeta = None
self.Chapter = {}
for Children in self.children:
if Children.__class__.__name__ == "DocumentMeta":
self.DocumentMeta = Children
elif Children.__class__.__name__ == "Chapter":
self.Chapter[Children.Nr] = Children
#self.Chapter.append(Children)
else:
print "Unknow Element"
def GetIndex(self):
return self.Chapter
File = "test.xml"
if os.path.exists(File):
Book = PyXO.Object.load(File)
#print """"Das Buch: %s wurde erstellt am %s""" % (Book.DocumentMeta.Title,
# Book.DocumentMeta.CreationDate
# )
#print Book.GetIndex()
else:
Book = PyBook()
Meta = DocumentMeta()
Meta.Title = "Documentation PyBook"
Meta.CreationDate = 100203230
Meta.Language = "de_DE"
Book.append(Meta)
MyChapter = Chapter(1, "Das ist ein Test")
MyChapter.append(PyXO.CData("Das ist ein Inhalt"))
Book.append(MyChapter)
Book.save(File)
Andreas
-
- Python-Forum Veteran
- Beiträge: 2010
- Registriert: Freitag 11. Oktober 2002, 18:00
- Wohnort: Salzburg
- Kontaktdaten:
Hi,
bis auf die to_xml-Methode von DocumentMeta passt das, ich würde sie so schreiben:
dann passen die Einrückungen im XML. Ich werd da wohl noch eine Formatierfunktion in PyXO einbauen.
Gruß
Dookie
bis auf die to_xml-Methode von DocumentMeta passt das, ich würde sie so schreiben:
Code: Alles auswählen
def to_xml(self, indent=0, indstr=PyXO.indstr, stream=None):
snip = """<DocumentMeta>
<Title>%s</Title>
<CreationDate>%s</CreationDate>
<Language>%s</Language>
</DocumentMeta>""" % (self.Title, self.CreationDate, self.Language)
snip = (indstr*indent)+snip.replace("\n", "\n"+indstr*indent)+"\n"
if stream is not None:
stream.write(snip)
else:
return snip
Gruß
Dookie
[code]#!/usr/bin/env python
import this[/code]
import this[/code]
-
- Python-Forum Veteran
- Beiträge: 2010
- Registriert: Freitag 11. Oktober 2002, 18:00
- Wohnort: Salzburg
- Kontaktdaten:
@ XT@ngel:
hab mir dein Beispiel nochmal zur Brust genommen.
so als kleines Weihnachtsgeschenk.
Dookie
hab mir dein Beispiel nochmal zur Brust genommen.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Modul: XmlBook
Description: Beschreibung
Version: 0.1
Copyright: 2004 by Fritz Cizmarov fritz@sol.at
Created: 24. Dez. 2004
Last modified: 25. Dez. 2004
License: free
Requirements: Python2.3
Exports: Classes and Functions to export
"""
import PyXO
import os, sys, re
class SimpleData(PyXO.Object):
__slots__ = ["Value"]
xml_attrs = {}
def __init__(self, value, **kw):
super(SimpleData, self).__init__(**kw)
if isinstance(value, list):
if value:
value = value[0]
else:
value = ""
self.Value = value
def __str__(self):
return self.Value
def to_xml(self, indent=0, indstr=PyXO.indstr, stream=None):
myind = indstr*indent
fmt = '%s<%s python_module=\"%s\">%s</%s>\n'
xml = fmt % (myind, self.__class__.__name__,
os.path.basename(__file__), self.Value,
self.__class__.__name__)
if stream:
stream.write(xml)
else:
return xml
class Title(SimpleData):
pass
class CreationDate(SimpleData):
pass
class Language(SimpleData):
pass
class DocumentMeta(PyXO.Container):
def get_child_by_type(self, the_type):
return [child for child in self.children if type(child) is the_type]
def __get_Title(self):
return self.get_child_by_type(Title)[0].Value
def __set_Title(self, value):
t = self.get_child_by_type(Title)
if t:
t[0].Value = value
else:
self.append(Title(value))
Title = property(__get_Title, __set_Title)
def __get_CreationDate(self):
return int(self.get_child_by_type(CreationDate)[0].Value)
def __set_CreationDate(self, value):
t = self.get_child_by_type(CreationDate)
if t:
t[0].Value = str(value)
else:
self.append(CreationDate(str(value)))
CreationDate = property(__get_CreationDate, __set_CreationDate)
def __get_Language(self):
return self.get_child_by_type(Language)[0].Value
def __set_Language(self, value):
t = self.get_child_by_type(Language)
if t:
t[0].Value = value
else:
self.append(Language(value))
Language = property(__get_Language, __set_Language)
class Chapter(PyXO.Container):
__slots__ = {"Nr": int ,
"Title": str
}
name = "Chapter"
def __init__(self, *args, **kw):
args = list(args)
if kw.has_key("Nr"):
self.Nr = kw.pop("Nr")
elif args and isinstance(args[0], int):
self.Nr = args.pop(0)
else:
self.Nr = 0
if kw.has_key("Title"):
self.Title= kw.pop("Title")
elif args > 1 and isinstance(args[0], basestring):
self.Title = args.pop(0)
else:
self.Title = "Unknown"
super(Chapter, self).__init__(*args, **kw)
def GetContent(self):
pass
class PyBook(PyXO.Root):
__slots__ = ["DocumentMeta", "Chapter"]
def __init__(self, *args, **kw):
super(PyBook, self).__init__(*args, **kw)
self.DocumentMeta = None
self.Chapter = {}
for Children in self.children:
if Children.__class__.__name__ == "DocumentMeta":
self.DocumentMeta = Children
elif Children.__class__.__name__ == "Chapter":
self.Chapter[Children.Nr] = Children
#self.Chapter.append(Children)
else:
print "Unknow Element"
def GetIndex(self):
return self.Chapter
File = "test.xml"
if os.path.exists(File):
Book = PyXO.Object.load(File)
#print """"Das Buch: %s wurde erstellt am %s""" % (Book.DocumentMeta.Title,
# Book.DocumentMeta.CreationDate
# )
#print Book.GetIndex()
Book.save(sys.stdout)
else:
Book = PyBook()
Meta = DocumentMeta()
Meta.Title = "Documentation PyBook"
Meta.CreationDate = 100203230
Meta.Language = "de_DE"
Book.append(Meta)
MyChapter = Chapter(1, "Das ist ein Test")
MyChapter.append(PyXO.CData("Das ist ein Inhalt"))
Book.append(MyChapter)
Book.save(File)
so als kleines Weihnachtsgeschenk.
Dookie
[code]#!/usr/bin/env python
import this[/code]
import this[/code]
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Hi
Ich hab eine Frage oder vielleicht ist es ein Vorschlag.
Wenn ich einen Container hab kann ich ja mit .append() neue Elemente hinzufügen. Könnte man diesen Elementen nicht gleich einen Namen zuweisenen.
Also ich möchte in einem Container direkt die __slots__ variabeln speichern können, wie bei xml_attrs = {'name':int} in ein dict schreiben. Geht sowas schon oder kann man das hinzufügen? Beim Laden natürlich gleich wieder zuweisen.
Ich denke so könnte dein PyXO noch einfacher werden.
childs ist bei mir jetzt wieder ein PyXO.Container.
Sowas in der Art, jetzt mach ich einfach in __init__ alle die ich drin haben möchte append(var)
Gruss
Ich hab eine Frage oder vielleicht ist es ein Vorschlag.
Wenn ich einen Container hab kann ich ja mit .append() neue Elemente hinzufügen. Könnte man diesen Elementen nicht gleich einen Namen zuweisenen.
Also ich möchte in einem Container direkt die __slots__ variabeln speichern können, wie bei xml_attrs = {'name':int} in ein dict schreiben. Geht sowas schon oder kann man das hinzufügen? Beim Laden natürlich gleich wieder zuweisen.
Ich denke so könnte dein PyXO noch einfacher werden.
Code: Alles auswählen
class test(PyXO.Container):
__slots__ = ['name','childs']
xml_attrs = {'name':int}
xml_container = ['childs']
Sowas in der Art, jetzt mach ich einfach in __init__ alle die ich drin haben möchte append(var)
Gruss
-
- Python-Forum Veteran
- Beiträge: 2010
- Registriert: Freitag 11. Oktober 2002, 18:00
- Wohnort: Salzburg
- Kontaktdaten:
Hi rayo,
da muss man bei xml etwas vorsichtig sein, da ein Attrubut name oft synonym für eine ID eines Objektes steht. PyXO.Container hat z.B. schon ein Attribut "name". Wenn gewünscht oder erforderlich, wird auch ein verstecktes Attribut "id" an die Objekte in der XML-Datei vergeben. Du kannst dann in deinen Eigenen Containern, wenn jedes enthaltene Objekt ein name-attribut hat auch eine Methode "get_child_by_name(self, the_name)" erstellen:
Gruß
Dookie
da muss man bei xml etwas vorsichtig sein, da ein Attrubut name oft synonym für eine ID eines Objektes steht. PyXO.Container hat z.B. schon ein Attribut "name". Wenn gewünscht oder erforderlich, wird auch ein verstecktes Attribut "id" an die Objekte in der XML-Datei vergeben. Du kannst dann in deinen Eigenen Containern, wenn jedes enthaltene Objekt ein name-attribut hat auch eine Methode "get_child_by_name(self, the_name)" erstellen:
Code: Alles auswählen
def get_child_by_name(self, the_name):
for child in self.children:
if child.name == the_name:
return child
return None
Dookie
[code]#!/usr/bin/env python
import this[/code]
import this[/code]
Danke für dein Weihnachtsgeschenk, Dookie!
Bin jetzt erst aus Mattighofen gekommen (wirst sicher kennen)
MfG
Andreas
Bin jetzt erst aus Mattighofen gekommen (wirst sicher kennen)
MfG
Andreas
Hallo Dookie,
ich hab nochmal eine Frage.
Ich hab ein XML Element das beliebig viele Attribute in unterschiedlichen Kombination haben kann. Zur zeit 21 Stück die mir bekannt sind.
Das Problem ist jetzt, das jeder Autor diesem Element beliebig Attribute hinzufügen kann da die Spezifikation nicht genauer regelt welche Attribute das Element haben darf.
Zur Zeit regele ich das so, das ich jedes einzelne der mir bekannten Attribute in __slots__ und xml_attrs schreibe und in der Init Methode jedes Attribut abfrage und entferne um das zurückschreiben von nicht vorhandenen Attributen zu verhindern setzte ich diese dann auf None.
Das funktioniert zwar, ist aber unflexibel.
Ich weiss das __slots__verhindert das ich einfach so Attribute hinzufügen kann. Und genau das ist mein Problem?
Wie muss ein PyXO.Object ausschauen damit ich das umgehen kann?
MfG und danke
Andreas
ich hab nochmal eine Frage.
Ich hab ein XML Element das beliebig viele Attribute in unterschiedlichen Kombination haben kann. Zur zeit 21 Stück die mir bekannt sind.
Das Problem ist jetzt, das jeder Autor diesem Element beliebig Attribute hinzufügen kann da die Spezifikation nicht genauer regelt welche Attribute das Element haben darf.
Zur Zeit regele ich das so, das ich jedes einzelne der mir bekannten Attribute in __slots__ und xml_attrs schreibe und in der Init Methode jedes Attribut abfrage und entferne um das zurückschreiben von nicht vorhandenen Attributen zu verhindern setzte ich diese dann auf None.
Das funktioniert zwar, ist aber unflexibel.
Ich weiss das __slots__verhindert das ich einfach so Attribute hinzufügen kann. Und genau das ist mein Problem?
Wie muss ein PyXO.Object ausschauen damit ich das umgehen kann?
MfG und danke
Andreas
Zuletzt geändert von XT@ngel am Freitag 14. Januar 2005, 19:12, insgesamt 1-mal geändert.
-
- Python-Forum Veteran
- Beiträge: 2010
- Registriert: Freitag 11. Oktober 2002, 18:00
- Wohnort: Salzburg
- Kontaktdaten:
Hi XT@ngel,
hmm eigentlich müssen laut XML-Spezifikation die Attribute von Elementen schon bekannt sein, insbesondere wenn du eine DTD oder XMLScheme als Beschreibung des Formates definieren willst.
__slots__ ist seit dem letzten Update nur noch optional, also du musst __slots__ nicht mehr verwenden. Zum Schreiben von eigenen Attributen müsstest du, in einer von PyXO.Object abgeleiteten Klasse attrs_to_xml redefinieren.
Ich habe gerade eine neue Version von PyXO hochgeladen, welche auch unbekannte Attribute aus der XML-Datei lesen kann, dann wird als Typ automatisch str verwendet und ein Warning ausgegeben. Das Ausgeben des Warnings kannst Du über einen Filter in warnings bei Bedarf abschalten oder in eine Exception umleiten.
Gruß
Dookie
hmm eigentlich müssen laut XML-Spezifikation die Attribute von Elementen schon bekannt sein, insbesondere wenn du eine DTD oder XMLScheme als Beschreibung des Formates definieren willst.
__slots__ ist seit dem letzten Update nur noch optional, also du musst __slots__ nicht mehr verwenden. Zum Schreiben von eigenen Attributen müsstest du, in einer von PyXO.Object abgeleiteten Klasse attrs_to_xml redefinieren.
Ich habe gerade eine neue Version von PyXO hochgeladen, welche auch unbekannte Attribute aus der XML-Datei lesen kann, dann wird als Typ automatisch str verwendet und ein Warning ausgegeben. Das Ausgeben des Warnings kannst Du über einen Filter in warnings bei Bedarf abschalten oder in eine Exception umleiten.
Gruß
Dookie
[code]#!/usr/bin/env python
import this[/code]
import this[/code]
Danke,
hab nicht mitbekommen das es eine neue Version gibt. Da Du das am anfang immer in diesen Thread geschrieben hast.
Aber super, läuft jetzt einwandfrei.
Es geht um OPML.
In der DTD steht:
Auf jedenfall Danke, funktioniert jetzt wie sein muss!
MfG
Andreas
hab nicht mitbekommen das es eine neue Version gibt. Da Du das am anfang immer in diesen Thread geschrieben hast.
Aber super, läuft jetzt einwandfrei.
Gut meine Darstellung war vieleicht schon etwas übertrieben.eigentlich müssen laut XML-Spezifikation die Attribute von Elementen schon bekannt sein
Es geht um OPML.
In der DTD steht:
Code: Alles auswählen
text CDATA #IMPLIED
type CDATA #IMPLIED
isComment (true|false) false
isBreakpoint (true|false) false
%OtherAttributes;

Auf jedenfall Danke, funktioniert jetzt wie sein muss!
MfG
Andreas
-
- Python-Forum Veteran
- Beiträge: 2010
- Registriert: Freitag 11. Oktober 2002, 18:00
- Wohnort: Salzburg
- Kontaktdaten:
So hab mal wieder ein Update gemacht, neben kleinen Codesäuberungen hab ich jetzt die Lizenz von "free" nach "Python license" geändert.
Hier nochmal der Link zu PyXO:
http://www.boa3d.de/python/modules/PyXO.php
Gruß
Dookie
Hier nochmal der Link zu PyXO:
http://www.boa3d.de/python/modules/PyXO.php
Gruß
Dookie
[code]#!/usr/bin/env python
import this[/code]
import this[/code]
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Damit PyXO nicht evtl. von der Bildfläche verschwindet, gab ich es inkl. readme in meinem SVN Server übernommen:
PyXO.py - Sourcecode | Revision Log | readme
Als erste aktion hab ich mal "cls" nach "self" umbenannt... Hatte mich ganz verwirrt, was "cls" bedeutet.
PyXO.py - Sourcecode | Revision Log | readme
Als erste aktion hab ich mal "cls" nach "self" umbenannt... Hatte mich ganz verwirrt, was "cls" bedeutet.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
cls ist die Namenskonvention, wenn man Metaclassen verwendet. Die Änderung würde ich rückgängig machen.jens hat geschrieben:Als erste aktion hab ich mal "cls" nach "self" umbenannt... Hatte mich ganz verwirrt, was "cls" bedeutet.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Dann muß ich wohl bisher nie über Metaclassen gestolpert sein. Denn cls hatte ich noch niergendwo gesehen:
Ich war ertmal nur verwirrt, was dieses cls ist und wo es her kommt. Erst als ich gesehen hab, das es in der Zeile, wo Methoden definiert werden, an der Stelle steht wo normalerweise self steht, ist mir ein Licht aufgegangen...
Ich find's aber als Erklärung zu wenig, warum man bei Metaclassen statt self cls nehmen sollte. Die Funktion ist doch die selbe, oder?
Ich war ertmal nur verwirrt, was dieses cls ist und wo es her kommt. Erst als ich gesehen hab, das es in der Zeile, wo Methoden definiert werden, an der Stelle steht wo normalerweise self steht, ist mir ein Licht aufgegangen...
Ich find's aber als Erklärung zu wenig, warum man bei Metaclassen statt self cls nehmen sollte. Die Funktion ist doch die selbe, oder?
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Jein. cls ist im Endeffekt wie selbst, nur macht man indem man cls nimmt noch mal explizit deutlich dass man es mit einem Klassen-Objekt (also einer Instanz des Typs type oder abgeleiteten Typs), und nicht mit einem Daten-Objekt (also einer Instanz des Typs object oder abgeleiteten Typs) zu tun hat.
Ich find die Konvention zwar in Metaklassen selbst auch unsinnig, da man mit dem self der Metaklasse spielt (bzw. die Methode eben das self der Metaklasse, was zwar ein Klassen-Objekt, aber eben eine Instanz der Klasse in der die Methode steckt ist), wo sie aber nicht unsinnig ist ist zum Beispiel bei __new__ einer Klasse, da man da wirklich das eigentliche Klassenobjekt bekommt.
Ich find die Konvention zwar in Metaklassen selbst auch unsinnig, da man mit dem self der Metaklasse spielt (bzw. die Methode eben das self der Metaklasse, was zwar ein Klassen-Objekt, aber eben eine Instanz der Klasse in der die Methode steckt ist), wo sie aber nicht unsinnig ist ist zum Beispiel bei __new__ einer Klasse, da man da wirklich das eigentliche Klassenobjekt bekommt.
--- Heiko.