simple xml pickle
Michael Stenner
mstenner at phy.duke.edu
Wed Sep 4 20:31:47 EDT 2002
On Wed, Sep 04, 2002 at 01:29:51PM -0400, Michael Stenner wrote:
> The xml marshalling does almost exactly what I want, and the
> modifications to make it "standalone" for Python 2.2 were very easy
> (patch forthcoming) so I may just stick with that. Nonetheless, I'll
> look at xml_pickle again and see what I can see.
Results:
With David's hint, xml_pickle.py was also fairly easy to make work
with python 2.2 in a standalone fashion. Here are the patches to
make both the PyXML marshaller and xml_pickle.py work as standalone
files with python 2.2 (probably 2.x, but I haven't tested it).
I haven't really tested either of these. I just tweeked them so
that they passed their own built-in tests.
generic.py.diff should be applied to xml.marshal.generic.py from
PyXML 0.8.
xml_pickle.py.diff should be applied to xml_pickle.py 0.51.
Now I just need to decide which I want to use :)
-Michael
--
Michael Stenner Office Phone: 919-660-2513
Duke University, Dept. of Physics mstenner at phy.duke.edu
Box 90305, Durham N.C. 27708-0305
-------------- next part --------------
--- generic.py.orig Wed Sep 4 20:19:58 2002
+++ generic.py Wed Sep 4 10:34:45 2002
@@ -6,7 +6,12 @@
from types import *
import string
-from xml.sax import saxlib, saxexts
+import xml.sax
+from xml.sax.handler import EntityResolver, DTDHandler, ContentHandler,\
+ ErrorHandler
+
+class HandlerBase(EntityResolver, DTDHandler, ContentHandler,\
+ ErrorHandler): pass
# Basic marshaller class, customizable by overriding it and
# changing various attributes and methods.
@@ -20,7 +25,7 @@
return cmp(ta.__name__, tb.__name__)
return cmp(a,b)
-class Marshaller(saxlib.HandlerBase):
+class Marshaller(HandlerBase):
# XML version and DOCTYPE declaration
PROLOGUE = '<?xml version="1.0"?>'
DTD = ""
@@ -251,7 +256,7 @@
TUPLE = {} ; LIST = {} ; DICT = {}
-class Unmarshaller(saxlib.HandlerBase):
+class Unmarshaller(HandlerBase):
# This dictionary maps element names to the names of starting and ending
# functions to call when unmarshalling them. My convention is to
# name them um_start_foo and um_end_foo, but do whatever you like.
@@ -314,9 +319,9 @@
def _load(self, file):
"Read one value from the open file"
- p=saxexts.make_parser()
- p.setDocumentHandler(self)
- p.parseFile(file)
+ p=xml.sax.make_parser()
+ p.setContentHandler(self)
+ p.parse(file)
assert len(self.data_stack) == 1
# leave the instance in a steady state
result = self.data_stack[0]
@@ -358,9 +363,9 @@
sm, em = self.unmarshal_meth[ name ]
if sm is not None: return sm(name,attrs)
- def characters(self, ch, start, length):
+ def characters(self, ch):
if self.accumulating_chars:
- self.data_stack[-1].append(ch[start:start+length])
+ self.data_stack[-1].append(ch)
def endElement(self, name):
# Call the ending method
-------------- next part --------------
--- xml_pickle.py.orig Tue Sep 3 18:38:48 2002
+++ xml_pickle.py Wed Sep 4 20:18:34 2002
@@ -206,7 +206,7 @@
'<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">\n',
'<PyObject class="%s" id="%s">\n'
% (_klass(self.py_obj),id_)]
- for name in dir(self.py_obj):
+ for name in self.py_obj.__dict__.keys():
xml_lines.append(_attr_tag(name, getattr(self, name)))
xml_lines.append('</PyObject>\n')
return string.join(xml_lines,'')
@@ -226,36 +226,36 @@
# Add all the subnodes to PyObject container
container = thing_from_dom(node, obj_from_node(node))
try:
- id = node.attributes[('', 'id')].value
+ id = node.attributes['id'].value
visited[id] = container
except KeyError:
pass
elif node.nodeName == 'attr':
try:
- node_type = node.attributes[('','type')].value
+ node_type = node.attributes['type'].value
except:
print "node", node.attributes, repr(node.attributes)
print node.attributes.keys()
raise ValueError # WHAT?!
- node_name = node.attributes[('', 'name')].value
+ node_name = node.attributes['name'].value
if node_name == '__parent__' and EXCLUDE_PARENT_ATTR:
# Do not pickle [xml_objectify] bookkeeping attribute
pass
elif node_type == 'None':
setattr(container, node_name, None)
elif node_type == 'numeric':
- node_val = safe_eval(node.attributes[('','value')].value)
+ node_val = safe_eval(node.attributes['value'].value)
setattr(container, node_name, node_val)
elif node_type == 'string':
- node_val = node.attributes[('','value')].value
+ node_val = node.attributes['value'].value
node_val = unsafe_string(node_val)
setattr(container, node_name, node_val)
elif node_type == 'list':
subcontainer = thing_from_dom(node, [])
setattr(container, node_name, subcontainer)
try:
- id = node.attributes[('', 'id')].value
+ id = node.attributes['id'].value
visited[id] = subcontainer
except KeyError:
pass
@@ -263,7 +263,7 @@
subcontainer = thing_from_dom(node, []) # use list then convert
setattr(container, node_name, tuple(subcontainer))
try:
- id = node.attributes[('', 'id')].value
+ id = node.attributes['id'].value
visited[id] = subcontainer
except KeyError:
pass
@@ -284,7 +284,7 @@
subcontainer = thing_from_dom(node, {})
setattr(container, node_name, subcontainer)
try:
- id = node.attributes[('', 'id')].value
+ id = node.attributes['id'].value
visited[id] = subcontainer
except KeyError:
pass
@@ -292,16 +292,16 @@
subcontainer = thing_from_dom(node, obj_from_node(node))
setattr(container, node_name, subcontainer)
try:
- id = node.attributes[('', 'id')].value
+ id = node.attributes['id'].value
visited[id] = subcontainer
except KeyError:
pass
elif node_type == 'mxDateTime':
- parts = node.attributes[('','value')].value.split()
+ parts = node.attributes['value'].value.split()
node_val = apply(mx.DateTime.DateTime,map(float,parts))
setattr(container, node_name, node_val)
elif node_type == 'ref':
- ref_id = node.attributes[('', 'refid')].value
+ ref_id = node.attributes['refid'].value
setattr(container, node_name, visited[ref_id])
elif node.nodeName in ['item', 'key', 'val']:
@@ -310,12 +310,12 @@
# all cases, elif's are defined for mutable types. Furthermore,
# there should only ever be *one* item in any key/val list,
# but we again rely on other validation of the XML happening.
- node_type = str(node.attributes[('','type')].value)
+ node_type = str(node.attributes['type'].value)
if node_type == 'numeric':
- node_val = safe_eval(node.attributes[('','value')].value)
+ node_val = safe_eval(node.attributes['value'].value)
container.append(node_val)
elif node_type == 'string':
- node_val = node.attributes[('','value')].value
+ node_val = node.attributes['value'].value
node_val = unsafe_string(node_val)
container.append(node_val)
elif node_type in ('list',array_type):
@@ -331,7 +331,7 @@
subcontainer = thing_from_dom(node, obj_from_node(node))
container.append(subcontainer)
elif node_type == 'mxDateTime':
- parts = node.attributes[('','value')].value.split()
+ parts = node.attributes['value'].value.split()
node_val = apply(mx.DateTime.DateTime,map(float,parts))
container.append(node_val)
@@ -350,7 +350,7 @@
# Get classname of object (with fallback to 'PyObject')
try:
if node.attributes:
- klass = node.attributes[('','class')].value
+ klass = node.attributes['class'].value
else:
klass = 'PyObject'
except KeyError: klass = 'PyObject'
@@ -452,7 +452,7 @@
visited[id(thing)] = 1
start_tag = start_tag + 'type="PyObject" class="%s" id="%s">\n' \
% (_klass(thing), id(thing))
- for name in dir(thing):
+ for name in thing.__dict__.keys():
tag_body.append(_attr_tag(name, getattr(thing, name), level+1))
elif '%s' % type(thing) == "<type 'SRE_Pattern'>":
# SRE_Pattern objects are extension objects, so not
More information about the Python-list
mailing list