[Zodb-checkins] CVS: ZODB4/src/persistence - pxml.py:1.1.2.1
Jeremy Hylton
jeremy at zope.com
Fri May 30 19:59:22 EDT 2003
Update of /cvs-repository/ZODB4/src/persistence
In directory cvs.zope.org:/tmp/cvs-serv24224
Added Files:
Tag: jeremy-xml-play-branch
pxml.py
Log Message:
A snippet of code for persistent xml objects.
=== Added File ZODB4/src/persistence/pxml.py ===
"""Simple persistent XML objects.
Inspired by Aaron Swartz's xmltramp.py.
http://www.aaronsw.com/2002/xmltramp/
"""
from persistence import Persistent
from xml.sax import make_parser
from xml.sax.handler import ContentHandler, EntityResolver, feature_namespaces
from xml.sax.saxutils import XMLGenerator
from cStringIO import StringIO
class Element(Persistent):
# The Handler class below manages the object's attributes directly
# to avoid name clashes between Element's methods and the xml
# content.
def __init__(self, name, attrs):
self._name = name
if attrs:
self._attrs = Attributes(attrs)
else:
self._attrs = None
self._content = None
self._children = None
def __repr__(self):
return "<%s element>" % self._name
def __str__(self):
return self._content
class Attributes(Persistent):
def __init__(self, attrdict):
self.__dict__.update(attrdict)
def toXml(elt):
f = StringIO()
gen = XMLGenerator(f)
gen.startDocument()
_genToXml(gen, elt)
gen.endDocument()
return f.getvalue()
def _genToXml(gen, elt):
if elt._attrs:
d = elt._attrs.__dict__
else:
d = {}
gen.startElement(elt._name, d)
gen.characters(elt._content)
for child in elt._children or []:
_genToXml(gen, child)
gen.endElement(elt._name)
class Handler(ContentHandler, EntityResolver):
def __init__(self):
self.stack = []
self.chars = []
self.root = None
def startElement(self, name, attrs):
self.stack.append(Element(name, attrs._attrs))
def endElement(self, name):
elt = self.stack.pop()
assert elt._name == name
elt._content = "".join(self.chars).strip()
self.chars = []
self.linkToParent(elt)
self.childAttrs(elt)
def linkToParent(self, elt):
if self.stack:
parent = self.stack[-1]
if parent._children is None:
parent._children = []
parent._children.append(elt)
else:
self.root = elt
def childAttrs(self, elt):
if not elt._children:
return
d = {}
for child in elt._children:
d.setdefault(child._name, []).append(child)
for k, v in d.items():
k = k.replace(":", "_")
if len(v) == 1:
setattr(elt, k, v[0])
else:
setattr(elt, k, v)
def characters(self, buf):
self.chars.append(buf)
def parse(s):
f = StringIO(s)
h = Handler()
p = make_parser()
p.setFeature(feature_namespaces, 0)
p.setContentHandler(h)
p.parse(f)
return h.root
More information about the Zodb-checkins
mailing list