mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-23 14:45:04 +08:00
Added the ActiveGrid IDE as a sample application
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33440 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import logging
|
||||
import cStringIO
|
||||
import traceback
|
||||
import sys
|
||||
import string
|
||||
import os
|
||||
|
||||
def classForName(className):
|
||||
pathList = className.split('.')
|
||||
moduleName = string.join(pathList[:-1], '.')
|
||||
code = __import__(moduleName)
|
||||
for name in pathList[1:]:
|
||||
code = code.__dict__[name]
|
||||
return code
|
||||
|
||||
def hasattrignorecase(object, name):
|
||||
for attr in dir(object):
|
||||
if attr.lower() == name.lower():
|
||||
return True
|
||||
for attr in dir(object):
|
||||
if attr.lower() == '_' + name.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def setattrignorecase(object, name, value):
|
||||
for attr in object.__dict__:
|
||||
if attr.lower() == name.lower():
|
||||
object.__dict__[attr] = value
|
||||
return
|
||||
## for attr in dir(object):
|
||||
## if attr.lower() == '_' + name.lower():
|
||||
## object.__dict__[attr] = value
|
||||
## return
|
||||
object.__dict__[name] = value
|
||||
|
||||
def getattrignorecase(object, name):
|
||||
for attr in object.__dict__:
|
||||
if attr.lower() == name.lower():
|
||||
return object.__dict__[attr]
|
||||
## for attr in dir(object):
|
||||
## if attr.lower() == '_' + name.lower():
|
||||
## return object.__dict__[attr]
|
||||
return object.__dict__[name]
|
||||
|
||||
|
||||
def defaultLoad(fileObject):
|
||||
xml = fileObject.read()
|
||||
loadedObject = xmlmarshaller.unmarshal(xml)
|
||||
if hasattr(fileObject, 'name'):
|
||||
loadedObject.fileName = os.path.abspath(fileObject.name)
|
||||
loadedObject.initialize()
|
||||
return loadedObject
|
||||
|
||||
def defaultSave(fileObject, objectToSave):
|
||||
xml = xmlmarshaller.marshal(objectToSave, prettyPrint=True)
|
||||
fileObject.write(xml)
|
||||
|
||||
|
||||
def clone(objectToClone):
|
||||
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True)
|
||||
clonedObject = xmlmarshaller.unmarshal(xml)
|
||||
if hasattr(objectToClone, 'fileName'):
|
||||
clonedObject.fileName = objectToClone.fileName
|
||||
clonedObject.initialize()
|
||||
return clonedObject
|
||||
|
||||
def exceptionToString(e):
|
||||
sio = cStringIO.StringIO()
|
||||
traceback.print_exception(e.__class__, e, sys.exc_traceback, file=sio)
|
||||
return sio.getvalue()
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: aglogging.py
|
||||
# Purpose: Utilities to help with logging
|
||||
#
|
||||
# Author: Jeff Norton
|
||||
#
|
||||
# Created: 01/04/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import traceback
|
||||
|
||||
global agTestMode
|
||||
agTestMode = False
|
||||
|
||||
def setTestMode(mode):
|
||||
global agTestMode
|
||||
if (mode):
|
||||
agTestMode = True
|
||||
else:
|
||||
agTestMode = False
|
||||
|
||||
def getTestMode():
|
||||
global agTestMode
|
||||
return agTestMode
|
||||
|
||||
def testMode(normalObj, testObj=None):
|
||||
if getTestMode():
|
||||
return testObj
|
||||
return normalObj
|
||||
|
||||
def toDiffableString(value):
|
||||
s = repr(value)
|
||||
ds = ""
|
||||
i = s.find(" at 0x")
|
||||
start = 0
|
||||
while (i >= 0):
|
||||
j = s.find(">", i)
|
||||
if (j < i):
|
||||
break
|
||||
ds += s[start:i]
|
||||
start = j
|
||||
i = s.find(" at 0x", start)
|
||||
return ds + s[start:]
|
||||
|
||||
def removeFileRefs(str):
|
||||
str = re.sub(r'(?<=File ")[^"]*(\\[^\\]*")(, line )[0-9]*', _fileNameReplacement, str)
|
||||
return str
|
||||
|
||||
def _fileNameReplacement(match):
|
||||
return "...%s" % match.group(1)
|
||||
|
||||
def getTraceback():
|
||||
extype, val, tb = sys.exc_info()
|
||||
tbs = "\n"
|
||||
for s in traceback.format_tb(tb):
|
||||
tbs += s
|
||||
return tbs
|
||||
|
||||
def reportException(out=None, stacktrace=False, diffable=False):
|
||||
extype, val, t = sys.exc_info()
|
||||
if (diffable):
|
||||
exstr = removeFileRefs(str(val))
|
||||
else:
|
||||
exstr = str(val)
|
||||
if (out == None):
|
||||
print "Got Exception = %s: %s" % (extype, exstr)
|
||||
else:
|
||||
print >> out, "Got Exception = %s: %s" % (extype, exstr)
|
||||
if (stacktrace):
|
||||
fmt = traceback.format_exception(extype, val, t)
|
||||
for s in fmt:
|
||||
if (diffable):
|
||||
s = removeFileRefs(s)
|
||||
if (out == None):
|
||||
print s
|
||||
else:
|
||||
print >> out, s
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: cachedloader.py
|
||||
# Purpose:
|
||||
#
|
||||
# Author: Joel Hare
|
||||
#
|
||||
# Created: 8/31/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import copy
|
||||
import os.path
|
||||
import string
|
||||
import cStringIO
|
||||
|
||||
import time
|
||||
|
||||
# TODO: Instantiate the database and create a pool
|
||||
|
||||
|
||||
class CachedLoader(object):
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
self.baseLoadDir = None
|
||||
|
||||
def fullPath(self, fileName):
|
||||
if os.path.isabs(fileName):
|
||||
absPath = fileName
|
||||
elif self.baseLoadDir:
|
||||
absPath = os.path.join(self.baseLoadDir, fileName)
|
||||
else:
|
||||
absPath = os.path.abspath(fileName)
|
||||
return absPath
|
||||
|
||||
def setPrototype(self, fileName, loadedFile):
|
||||
absPath = self.fullPath(fileName)
|
||||
mtime = time.time() + 31536000.0 # Make sure prototypes aren't replaced by files on disk
|
||||
self.cache[absPath] = (mtime, loadedFile)
|
||||
|
||||
def update(self, loader):
|
||||
self.cache.update(loader.cache)
|
||||
|
||||
def clear(self):
|
||||
self.cache.clear()
|
||||
|
||||
def delete(self, fileName):
|
||||
absPath = self.fullPath(fileName)
|
||||
del self.cache[absPath]
|
||||
|
||||
def needsLoad(self, fileName):
|
||||
absPath = self.fullPath(fileName)
|
||||
try:
|
||||
cached = self.cache[absPath]
|
||||
cachedTime = cached[0]
|
||||
if cachedTime >= os.path.getmtime(absPath):
|
||||
return False
|
||||
except KeyError:
|
||||
pass
|
||||
return True
|
||||
|
||||
def load(self, fileName, loader):
|
||||
absPath = self.fullPath(fileName)
|
||||
loadedFile = None
|
||||
try:
|
||||
cached = self.cache[absPath]
|
||||
except KeyError:
|
||||
cached = None
|
||||
|
||||
if cached:
|
||||
cachedTime = cached[0]
|
||||
# ToDO We might need smarter logic for checking if a file needs to be reloaded
|
||||
# ToDo We need a way to disable checking if this is a production server
|
||||
if cachedTime >= os.path.getmtime(absPath):
|
||||
loadedFile = cached[1]
|
||||
|
||||
if not loadedFile:
|
||||
targetFile = file(absPath)
|
||||
try:
|
||||
mtime = os.path.getmtime(absPath)
|
||||
loadedFile = loader(targetFile)
|
||||
self.cache[absPath] = (mtime, loadedFile)
|
||||
finally:
|
||||
targetFile.close()
|
||||
return loadedFile
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: dependencymgr.py
|
||||
# Purpose: Dependency Manager
|
||||
#
|
||||
# Author: Jeff Norton
|
||||
#
|
||||
# Created: 01/28/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
DM_NO_ID = 0
|
||||
DM_ID_ATTR = "_DependencyMgr__ID"
|
||||
|
||||
##class ManageableObject(object):
|
||||
##
|
||||
## def __init__(self):
|
||||
## self.__id = DM_NO_ID
|
||||
##
|
||||
## def __repr__(self):
|
||||
## return "<ManageableObject id = %s>" % self.__id
|
||||
##
|
||||
## def __getID(self):
|
||||
## return self.__id
|
||||
##
|
||||
## def __setID(self, value):
|
||||
## if (self.__id != DM_NO_ID):
|
||||
## raise DependencyMgrException("Cannot set the dependency ID on object %s to \"%s\" because it already has one (\"%s\")." % (repr(self), value, self.__id))
|
||||
## self.__id = value
|
||||
##
|
||||
## _DependencyMgr__ID = property(__getID, __setID)
|
||||
|
||||
class DependencyMgr(object):
|
||||
|
||||
def __init__(self):
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
self.__dependencies = {}
|
||||
self.__lastID = DM_NO_ID
|
||||
|
||||
def addDependency(self, parent, child):
|
||||
pid = self._initObjectID(parent)
|
||||
try:
|
||||
parentCollection = self.__dependencies[pid]
|
||||
except KeyError:
|
||||
parentCollection = self._newDependencyCollection()
|
||||
self.__dependencies[pid] = parentCollection
|
||||
if (child not in parentCollection):
|
||||
parentCollection.append(child)
|
||||
|
||||
def removeDependency(self, parent, child):
|
||||
pid = self._getObjectID(parent)
|
||||
if (pid != DM_NO_ID):
|
||||
try:
|
||||
parentCollection = self.__dependencies[pid]
|
||||
parentCollection.remove(child)
|
||||
if (len(parentCollection) == 0):
|
||||
del self.__dependencies[pid]
|
||||
except KeyError, ValueError:
|
||||
pass
|
||||
|
||||
def clearDependencies(self, parent):
|
||||
"Returns a list of objects or an empty list if no dependencies exist as for getDependencies, and then removes the dependency list."
|
||||
pid = self._getObjectID(parent)
|
||||
try:
|
||||
deps = self.__dependencies[pid]
|
||||
del self.__dependencies[pid]
|
||||
return deps
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def hasDependency(self, parent):
|
||||
"Returns a boolean"
|
||||
return (self._getObjectID(parent) in self.__dependencies)
|
||||
|
||||
def getDependencies(self, parent):
|
||||
"Returns a list of objects or an empty list if no dependencies exist."
|
||||
try:
|
||||
return self.__dependencies[self._getObjectID(parent)]
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def dumpState(self, out):
|
||||
"Writes the state of the dependency manager (as reported by getState) to out"
|
||||
for line in self.getState():
|
||||
print >> out, line
|
||||
|
||||
def getState(self):
|
||||
"Returns the state of the dependency manager including all managed objects as a list of strings"
|
||||
out = []
|
||||
out.append("DependencyMgr %s has %i parent objects, last id assigned is %i" % (repr(self), len(self.__dependencies), self.__lastID))
|
||||
for key, val in self.__dependencies.iteritems():
|
||||
out.append("Object %s has dependents: %s " % (repr(key), ", ".join([repr(d) for d in val])))
|
||||
return out
|
||||
|
||||
def _initObjectID(self, obj):
|
||||
try:
|
||||
id = getattr(obj, DM_ID_ATTR)
|
||||
except AttributeError:
|
||||
id = DM_NO_ID
|
||||
if (id == DM_NO_ID):
|
||||
id = self._newID()
|
||||
setattr(obj, DM_ID_ATTR, id)
|
||||
return id
|
||||
|
||||
def _getObjectID(self, obj):
|
||||
try:
|
||||
id = getattr(obj, DM_ID_ATTR)
|
||||
except AttributeError:
|
||||
id = DM_NO_ID
|
||||
return id
|
||||
|
||||
def _newID(self):
|
||||
self.__lastID += 1
|
||||
return self.__lastID
|
||||
|
||||
def _newDependencyCollection(self):
|
||||
return []
|
||||
|
||||
globalDM = DependencyMgr()
|
||||
|
||||
def addDependency(parent, child):
|
||||
getGlobalDM().addDependency(parent, child)
|
||||
|
||||
def removeDependency(parent, child):
|
||||
getGlobalDM().removeDependency(parent, child)
|
||||
|
||||
def clearDependencies(parent):
|
||||
return getGlobalDM().clearDependencies(parent)
|
||||
|
||||
def hasDependency(parent):
|
||||
return getGlobalDM().hasDependency(parent)
|
||||
|
||||
def getDependencies(parent):
|
||||
return getGlobalDM().getDependencies(parent)
|
||||
|
||||
def getState():
|
||||
return getGlobalDM().getState()
|
||||
|
||||
def dumpState(out):
|
||||
getGlobalDM().dumpState(out)
|
||||
|
||||
def getGlobalDM():
|
||||
return globalDM
|
||||
@@ -0,0 +1,39 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: fileutils.py
|
||||
# Purpose: Active grid miscellaneous utilities
|
||||
#
|
||||
# Author: Jeff Norton
|
||||
#
|
||||
# Created: 12/10/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
|
||||
def createFile(filename, mode='w'):
|
||||
f = None
|
||||
try:
|
||||
f = file(filename, mode)
|
||||
except:
|
||||
os.makedirs(filename[:filename.rindex(os.sep)])
|
||||
f = file(filename, mode)
|
||||
return f
|
||||
|
||||
def compareFiles(file1, file2):
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
while True:
|
||||
line1 = file1.readline()
|
||||
line2 = file2.readline()
|
||||
if (len(line1) == 0):
|
||||
if (len(line2) == 0):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
elif (len(line2) == 0):
|
||||
return -1
|
||||
elif (line1 != line2):
|
||||
return -1
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: gettersetter.py
|
||||
# Purpose:
|
||||
#
|
||||
# Author: Peter Yared
|
||||
#
|
||||
# Created: 7/28/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
def gettersetter(list):
|
||||
for attr in list:
|
||||
lowercase = attr[0].lower() + attr[1:]
|
||||
uppercase = attr[0].upper() + attr[1:]
|
||||
print " def get%s(self):" % uppercase
|
||||
print " return self._%s" % lowercase
|
||||
print
|
||||
print " def set%s(self, %s):" % (uppercase, lowercase)
|
||||
print " self._%s = %s" % (lowercase, lowercase)
|
||||
print
|
||||
|
||||
def listgettersetter(list):
|
||||
for attr in list:
|
||||
lowercase = attr[0].lower() + attr[1:]
|
||||
uppercase = attr[0].upper() + attr[1:]
|
||||
print " def get%s(self):" % uppercase
|
||||
print " return self._%s" % lowercase
|
||||
print
|
||||
print " def add%s(self, %s):" % (uppercase[:-1], lowercase[:-1])
|
||||
print " self._%s.append(%s)" % (lowercase, lowercase[:-1])
|
||||
print
|
||||
print " def remove%s(self, %s):" % (uppercase[:-1], lowercase[:-1])
|
||||
print " self._%s.remove(%s)" % (lowercase, lowercase[:-1])
|
||||
print
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: xmlmarshallertests.py
|
||||
# Purpose:
|
||||
#
|
||||
# Author: John Spurling
|
||||
#
|
||||
# Created: 8/16/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
import xmlmarshaller
|
||||
from xmlprettyprinter import xmlprettyprint
|
||||
|
||||
marshalledPersonObject = """
|
||||
<person objtype="Person">
|
||||
<firstName>Albert</firstName>
|
||||
<lastName>Camus</lastName>
|
||||
<address>23 Absurd St.</address>
|
||||
<city>Ennui</city>
|
||||
<state>MO</state>
|
||||
<zip>54321</zip>
|
||||
<_phoneNumber>808-303-2323</_phoneNumber>
|
||||
<favoriteWords objtype="list">
|
||||
<item>angst</item>
|
||||
<item>ennui</item>
|
||||
<item>existence</item>
|
||||
</favoriteWords>
|
||||
<weight objtype="float">150</weight>
|
||||
</person>
|
||||
"""
|
||||
|
||||
marshalledint = '''
|
||||
<item objtype="int">23</item>
|
||||
'''
|
||||
|
||||
marshalledlist = '''
|
||||
<mylist objtype="list">
|
||||
<item>foo</item>
|
||||
<item>bar</item>
|
||||
</mylist>
|
||||
'''
|
||||
|
||||
## a dummy class taken from the old XmlMarshaller module.
|
||||
## class Person:
|
||||
## def __init__(self):
|
||||
## # These are not necessary but are nice if you want to tailor
|
||||
## # the Python object <-> XML binding
|
||||
|
||||
## # The xml element name to use for this object, otherwise it
|
||||
## # will use a fully qualified Python name like __main__.Person
|
||||
## # which can be ugly.
|
||||
## self.__xmlname__ = "person"
|
||||
## self.firstName = None
|
||||
## self.lastName = None
|
||||
## self.addressLine1 = None
|
||||
## self.addressLine2 = None
|
||||
## self.city = None
|
||||
## self.state = None
|
||||
## self.zip = None
|
||||
## self._phoneNumber = None
|
||||
## self.favoriteWords = None
|
||||
## self.weight = None
|
||||
class Person:
|
||||
__xmlflattensequence__ = {'asequence': ('the_earth_is_flat',)}
|
||||
|
||||
class XmlMarshallerTestFunctions(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
'''common setup code goes here.'''
|
||||
pass
|
||||
|
||||
def testInt(self):
|
||||
xml = xmlmarshaller.marshal(1)
|
||||
print "\n#########################################"
|
||||
print "# testString test case #"
|
||||
print "#########################################"
|
||||
print "marshalled int object:\n"
|
||||
print xmlprettyprint(xml)
|
||||
|
||||
def testDict(self):
|
||||
xml = xmlmarshaller.marshal({'one': 1,
|
||||
'two': 2,
|
||||
'three': 3})
|
||||
print "\n#########################################"
|
||||
print "# testString test case #"
|
||||
print "#########################################"
|
||||
print "marshalled dict object:\n"
|
||||
print xmlprettyprint(xml)
|
||||
|
||||
def testBool(self):
|
||||
xmltrue = xmlmarshaller.marshal(True)
|
||||
xmlfalse = xmlmarshaller.marshal(False)
|
||||
print "\n#########################################"
|
||||
print "# testBool test case #"
|
||||
print "#########################################"
|
||||
print "marshalled boolean true object:\n"
|
||||
print xmlprettyprint(xmltrue)
|
||||
print "\nmarshalled boolean false object:\n"
|
||||
print xmlprettyprint(xmlfalse)
|
||||
pytrue = xmlmarshaller.unmarshal(xmltrue)
|
||||
assert pytrue is True
|
||||
pyfalse = xmlmarshaller.unmarshal(xmlfalse)
|
||||
assert pyfalse is False
|
||||
|
||||
def testString(self):
|
||||
xml = xmlmarshaller.marshal(
|
||||
"all your marshalled objects are belong to us")
|
||||
print "\n#########################################"
|
||||
print "# testString test case #"
|
||||
print "#########################################"
|
||||
print xmlprettyprint(xml)
|
||||
|
||||
def testEmptyElement(self):
|
||||
person = Person()
|
||||
person.firstName = "Albert"
|
||||
person.__xmlattributes__ = ('firstName',)
|
||||
xml = xmlmarshaller.marshal(person, 'person')
|
||||
print "\n#########################################"
|
||||
print "# testEmptyElement test case #"
|
||||
print "#########################################"
|
||||
print xml
|
||||
assert (xml == """<person objtype="__main__.Person" firstName="Albert"/>""")
|
||||
|
||||
def testXMLFlattenSequence(self):
|
||||
person = Person()
|
||||
person.asequence = ('one', 'two')
|
||||
xml = xmlmarshaller.marshal(person, 'person')
|
||||
print "\n#########################################"
|
||||
print "# testXMLFlattenSequence test case #"
|
||||
print "#########################################"
|
||||
print xml
|
||||
assert (xml == """<person objtype="__main__.Person"><the_earth_is_flat>one</the_earth_is_flat><the_earth_is_flat>two</the_earth_is_flat></person>""")
|
||||
unmarshalledperson = xmlmarshaller.unmarshal(xml)
|
||||
assert(hasattr(unmarshalledperson, 'asequence'))
|
||||
assert(len(unmarshalledperson.asequence) == 2)
|
||||
|
||||
def testInstance(self):
|
||||
print "\n#########################################"
|
||||
print "# testInstance test case #"
|
||||
print "#########################################"
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.alist = [1,2]
|
||||
self.astring = 'f00'
|
||||
f = Foo()
|
||||
xml = xmlmarshaller.marshal(f, 'foo')
|
||||
print xml
|
||||
|
||||
def testPerson(self):
|
||||
person = Person()
|
||||
person.firstName = "Albert"
|
||||
person.lastName = "Camus"
|
||||
person.addressLine1 = "23 Absurd St."
|
||||
person.city = "Ennui"
|
||||
person.state = "MO"
|
||||
person.zip = "54321"
|
||||
person._phoneNumber = "808-303-2323"
|
||||
person.favoriteWords = ['angst', 'ennui', 'existence']
|
||||
person.weight = 150
|
||||
# __xmlattributes__ = ('fabulousness',)
|
||||
person.fabulousness = "tres tres"
|
||||
xml = xmlmarshaller.marshal(person)
|
||||
print "\n#########################################"
|
||||
print "# testPerson test case #"
|
||||
print "#########################################"
|
||||
print "Person object marshalled into XML:\n"
|
||||
print xml
|
||||
# When encountering a "person" element, use the Person class
|
||||
## elementMappings = { "person" : Person }
|
||||
## obj = unmarshal(xml, elementMappings = elementMappings)
|
||||
## print "Person object recreated from XML with attribute types indicated:"
|
||||
## print obj.person.__class__
|
||||
## for (attr, value) in obj.person.__dict__.items():
|
||||
## if not attr.startswith("__"):
|
||||
## print attr, "=", value, type(value)
|
||||
## print
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,63 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: xmlprettyprinter.py
|
||||
# Purpose:
|
||||
#
|
||||
# Author: John Spurling
|
||||
#
|
||||
# Created: 9/21/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
import xml.sax
|
||||
import xml.sax.handler
|
||||
|
||||
|
||||
class XMLPrettyPrinter(xml.sax.ContentHandler):
|
||||
def __init__(self, indentationChar=' ', newlineChar='\n'):
|
||||
self.xmlOutput = ''
|
||||
self.indentationLevel = 0
|
||||
self.indentationChar = indentationChar
|
||||
self.elementStack = []
|
||||
self.newlineChar = newlineChar
|
||||
self.hitCharData = False
|
||||
|
||||
## ContentHandler methods
|
||||
def startElement(self, name, attrs):
|
||||
indentation = self.newlineChar + (self.indentationLevel * self.indentationChar)
|
||||
# build attribute string
|
||||
attrstring = ''
|
||||
for attr in attrs.getNames():
|
||||
value = attrs[attr]
|
||||
attrstring += ' %s="%s"' % (attr, value)
|
||||
self.xmlOutput += '%s<%s%s>' % (indentation, name, attrstring)
|
||||
self.indentationLevel += 1
|
||||
self.elementStack.append(name)
|
||||
self.hitCharData = False
|
||||
|
||||
def characters(self, content):
|
||||
self.xmlOutput += content
|
||||
self.hitCharData = True
|
||||
|
||||
def endElement(self, name):
|
||||
self.indentationLevel -= 1
|
||||
indentation = ''
|
||||
if not self.hitCharData:
|
||||
## indentation += self.newlineChar + (self.indentationLevel * self.indentationChar)
|
||||
indentation += self.indentationLevel * self.indentationChar
|
||||
else:
|
||||
self.hitCharData = False
|
||||
self.xmlOutput += '%s</%s>%s' % (indentation, self.elementStack.pop(), self.newlineChar)
|
||||
|
||||
def getXMLString(self):
|
||||
return self.xmlOutput[1:]
|
||||
|
||||
def xmlprettyprint(xmlstr, spaces=4):
|
||||
xpp = XMLPrettyPrinter(indentationChar=' ' * spaces)
|
||||
xml.sax.parseString(xmlstr, xpp)
|
||||
return xpp.getXMLString()
|
||||
|
||||
if __name__ == '__main__':
|
||||
simpleTestString = """<one>some text<two anattr="booga">two's data</two></one>"""
|
||||
print prettyprint(simpleTestString)
|
||||
|
||||
Reference in New Issue
Block a user