[XML-SIG] SAX, freeze problem
Gregor Mosheh
stigmata@blackangel.net
Tue, 2 Apr 2002 20:25:27 -0800 (PST)
I am unable to freeze Python programs that use SAX, apparently due to
failed imports. I saw an article (and in the reeze docs) mentioning that
some extension modules, such as SAX, don't have enough explicit import
statements for the freezer to find and import everything.
I'm trying to freeze the program below (the goal: take an array of objects
and XML-encode their attributes), and I'd much appreciate it if someone
has a list/reference of the changes I can make to allow this program to be
frozen.
The problem seems to be in xml.sax.writer, specifically.
I do have another question, incidentally: is SAX portable to Windows? That
is, has anyone using Win32/MSVC++ ever successfully compiled expat and
used it with SAX/Python?
import xml.sax, xml.sax.writer, xml.sax.handler
import cStringIO
import re
from re import sub
from re import match
privateattribute = re.compile("^_")
# encode() takes a list of objects and encodes their attributes
class XMLEncoder(xml.sax.writer.PrettyPrinter):
def startDocument(self):
pass
def encode(objectlist,includeprivate=0):
# use a StringIO buffer to hold the string, cuz the XML stuff requires streams (bleh)
buffer = cStringIO.StringIO()
saxout = XMLEncoder(buffer)
saxout.startDocument()
saxout.startElement("objects",{})
# go thru the list of objects...
for thisobject in objectlist:
# populate thisobjecthash with the object's attributes, skipping privates if necessary
thisobjecthash = {}
for property in dir(thisobject):
if not match(privateattribute,property) or includeprivate:
content = str(getattr(thisobject,property))
thisobjecthash[property] = content
# it was empty? must not not have been interesting, so skip it
if not thisobjecthash:
continue
saxout.startElement("object",thisobjecthash)
saxout.endElement("object")
saxout.endElement("objects")
saxout.endDocument()
return buffer.getvalue()
# decode() takes an XML string and returns a tuple of hashes. the hashes represent the attributes of objects
class XMLDecoder(xml.sax.handler.ContentHandler):
def __init__(self):
self.objectlist = []
def startElement(self, name, attrs):
if name=='object':
newDict = {}
for key, value in attrs.items():
newDict[str(key)] = value
self.objectlist.append(newDict)
def decode(xmlstring):
try:
xmlhandler = XMLDecoder()
xml.sax.parseString(xmlstring, xmlhandler)
return tuple(xmlhandler.objectlist)
except:
return
# an example, if this module is executed
def runexample():
# create an array of instances of this class, then encode it
class Example:
def __init__(self,x,y):
self.X = x
self.Y = y
self.ObjectClass = 'Example'
objectlist = [ Example(1,'this has "quote marks" in it') , Example(2,'abc>&<def') , Example(3,'\312') ]
encoded_as_xml = encode(objectlist)
decoded_into_hashes = decode(encoded_as_xml)
print "Three Example objects encoded as XML:"
print encoded_as_xml
print "\n"
print "The XML decodes back into this:"
print decoded_into_hashes
print "\n"
if __name__ == '__main__':
runexample()