DocView and ActiveGrid IDE updates from Morgan Hua:
New Features: In Tab-View mode, Ctrl-number will take the user to the numbered tab view. Modified files now show an '*' astrisk in the view title. Debugger framework can now support PHP debugging. Not important for python development, but at least that means the debugger framework is more generalized. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38852 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# Name: xmlmarshaller.py
|
||||
# Purpose:
|
||||
#
|
||||
# Authors: John Spurling, Joel Hare, Alan Mullendore
|
||||
# Authors: John Spurling, Joel Hare, Jeff Norton, Alan Mullendore
|
||||
#
|
||||
# Created: 7/28/04
|
||||
# CVS-ID: $Id$
|
||||
@@ -16,14 +16,18 @@ import logging
|
||||
ifDefPy()
|
||||
import xml.sax
|
||||
import xml.sax.handler
|
||||
import xml.sax.saxutils
|
||||
import datetime
|
||||
endIfDef()
|
||||
import xml.sax.saxutils as saxutils
|
||||
import activegrid.util.utillang as utillang
|
||||
import activegrid.util.objutils as objutils
|
||||
import activegrid.util.sysutils as sysutils
|
||||
import activegrid.util.aglogging as aglogging
|
||||
|
||||
MODULE_PATH = "__main__"
|
||||
|
||||
## ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
|
||||
##unboundedVal = 2147483647 # value used for maxOccurs == "unbounded"
|
||||
|
||||
"""
|
||||
Special attributes that we recognize:
|
||||
@@ -109,7 +113,6 @@ __xmlcdatacontent__ = "messyContent"
|
||||
|
||||
global xmlMarshallerLogger
|
||||
xmlMarshallerLogger = logging.getLogger("activegrid.util.xmlmarshaller.marshal")
|
||||
xmlMarshallerLogger.setLevel(aglogging.LEVEL_WARN)
|
||||
# INFO : low-level info
|
||||
# DEBUG : debugging info
|
||||
|
||||
@@ -184,6 +187,7 @@ DICT_ITEM_VALUE_NAME = "value"
|
||||
################################################################################
|
||||
|
||||
def setattrignorecase(object, name, value):
|
||||
## print "[setattrignorecase] name = %s, value = %s" % (name, value)
|
||||
if (name not in object.__dict__):
|
||||
namelow = name.lower()
|
||||
for attr in object.__dict__:
|
||||
@@ -193,27 +197,95 @@ def setattrignorecase(object, name, value):
|
||||
object.__dict__[name] = value
|
||||
|
||||
def getComplexType(obj):
|
||||
if (hasattr(obj, "_instancexsdcomplextype")):
|
||||
return obj._instancexsdcomplextype
|
||||
if (hasattr(obj, "__xsdcomplextype__")):
|
||||
return obj.__xsdcomplextype__
|
||||
return None
|
||||
|
||||
def _objectfactory(objname, objargs=None, objclass=None):
|
||||
"dynamically create an object based on the objname and return it."
|
||||
## print "[objectfactory] objname [%s]" % (objname)
|
||||
def _objectfactory(objtype, objargs=None, objclass=None):
|
||||
"dynamically create an object based on the objtype and return it."
|
||||
if not isinstance(objargs, list):
|
||||
objargs = [objargs]
|
||||
if (objclass != None):
|
||||
obj = None
|
||||
if (len(objargs) > 0):
|
||||
if (hasattr(objclass, "__xmlcdatacontent__")):
|
||||
obj = objclass()
|
||||
contentAttr = obj.__xmlcdatacontent__
|
||||
obj.__dict__[contentAttr] = str(objargs[0])
|
||||
return obj
|
||||
return objclass(*objargs)
|
||||
else:
|
||||
obj = objclass(*objargs)
|
||||
else:
|
||||
return objclass()
|
||||
return objutils.newInstance(objname, objargs)
|
||||
obj = objclass()
|
||||
if ((obj != None) and (hasattr(obj, 'postUnmarshal'))):
|
||||
obj.postUnmarshal()
|
||||
return obj
|
||||
return objutils.newInstance(objtype, objargs)
|
||||
|
||||
class GenericXMLObject(object):
|
||||
def __init__(self, content=None):
|
||||
if content != None:
|
||||
self._content = content
|
||||
self.__xmlcontent__ = '_content'
|
||||
|
||||
def __str__(self):
|
||||
return "GenericXMLObject(%s)" % objutils.toDiffableString(self.__dict__)
|
||||
|
||||
def setXMLAttributes(self, xmlName, attrs=None, children=None, nsMap=None, defaultNS=None):
|
||||
if xmlName != None:
|
||||
i = xmlName.rfind(':')
|
||||
if i < 0:
|
||||
self.__xmlname__ = xmlName
|
||||
if defaultNS != None:
|
||||
self.__xmldefaultnamespace__ = str(defaultNS)
|
||||
else:
|
||||
self.__xmlname__ = xmlName[i+1:]
|
||||
prefix = xmlName[:i]
|
||||
if nsMap.has_key(prefix):
|
||||
self.__xmldefaultnamespace__ = str(nsMap[prefix])
|
||||
if attrs != None:
|
||||
for attrname, attr in attrs.items():
|
||||
attrname = str(attrname)
|
||||
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
|
||||
pass
|
||||
elif attrname == "objtype":
|
||||
pass
|
||||
else:
|
||||
if not hasattr(self, '__xmlattributes__'):
|
||||
self.__xmlattributes__ = []
|
||||
i = attrname.rfind(':')
|
||||
if i >= 0:
|
||||
prefix = attrname[:i]
|
||||
attrname = attrname[i+1:]
|
||||
if not hasattr(self, '__xmlattrnamespaces__'):
|
||||
self.__xmlattrnamespaces__ = {}
|
||||
if self.__xmlattrnamespaces__.has_key(prefix):
|
||||
alist = self.__xmlattrnamespaces__[prefix]
|
||||
else:
|
||||
alist = []
|
||||
alist.append(attrname)
|
||||
self.__xmlattrnamespaces__[prefix] = alist
|
||||
self.__xmlattributes__.append(attrname)
|
||||
if hasattr(self, '__xmlattributes__'):
|
||||
self.__xmlattributes__.sort()
|
||||
if children != None and len(children) > 0:
|
||||
childList = []
|
||||
flattenList = {}
|
||||
for childname, child in children:
|
||||
childstr = str(childname)
|
||||
if childstr in childList:
|
||||
if not flattenList.has_key(childstr):
|
||||
flattenList[childstr] = (childstr,)
|
||||
else:
|
||||
childList.append(childstr)
|
||||
if len(flattenList) > 0:
|
||||
self.__xmlflattensequence__ = flattenList
|
||||
|
||||
def initialize(self, arg1=None):
|
||||
pass
|
||||
|
||||
|
||||
class Element:
|
||||
def __init__(self, name, attrs=None, xsname=None):
|
||||
self.name = name
|
||||
@@ -222,9 +294,11 @@ class Element:
|
||||
self.children = []
|
||||
self.objclass = None
|
||||
self.xsname = xsname
|
||||
self.objtype = None
|
||||
|
||||
def getobjtype(self):
|
||||
objtype = self.attrs.get("objtype")
|
||||
# objtype = self.attrs.get("objtype")
|
||||
objtype = self.objtype
|
||||
if (objtype == None):
|
||||
if (len(self.children) > 0):
|
||||
objtype = "dict"
|
||||
@@ -238,16 +312,35 @@ class NsElement(object):
|
||||
self.targetNS = None
|
||||
self.defaultNS = None
|
||||
self.prefix = None
|
||||
|
||||
def isEmpty(self):
|
||||
return ((self.nsMap == {}) and (self.targetNS == None) and (self.defaultNS == None))
|
||||
|
||||
def __str__(self):
|
||||
if self.prefix == None:
|
||||
strVal = 'prefix = None; '
|
||||
else:
|
||||
strVal = 'prefix = "%s"; ' % (self.prefix)
|
||||
if self.targetNS == None:
|
||||
strVal += 'targetNS = None; '
|
||||
else:
|
||||
strVal += 'targetNS = "%s"; ' % (self.targetNS)
|
||||
if self.defaultNS == None:
|
||||
strVal += 'defaultNS = None; '
|
||||
else:
|
||||
strVal += 'defaultNS = "%s"; ' % (self.defaultNS)
|
||||
if len(self.nsMap) == 0:
|
||||
strVal += 'nsMap = None; '
|
||||
else:
|
||||
strVal += 'nsMap = {'
|
||||
for ik, iv in self.nsMap.iteritems():
|
||||
strVal += '%s=%s; ' % (ik,iv)
|
||||
strVal += '}'
|
||||
return strVal
|
||||
|
||||
def setKnownTypes(self, masterKnownTypes, masterKnownNamespaces, parentNSE):
|
||||
# if we're a nested element, extend our parent element's mapping
|
||||
if parentNSE != None:
|
||||
self.knownTypes = parentNSE.knownTypes.copy()
|
||||
# but if we have a different default namespace, replace the parent's default mappings
|
||||
if parentNSE.defaultNS != self.defaultNS:
|
||||
if (self.defaultNS != None) and (parentNSE.defaultNS != self.defaultNS):
|
||||
newKT = self.knownTypes.copy()
|
||||
for tag in newKT:
|
||||
if tag.find(':') < 0:
|
||||
@@ -283,7 +376,6 @@ class NsElement(object):
|
||||
self.knownTypes[knownTagName] = mapClass
|
||||
else: # e.g. "ItemSearchRequest"
|
||||
self.knownTypes[tag] = mapClass
|
||||
## print 'mapping <%s> to class "%s"' % (tag, mapClass.__name__)
|
||||
|
||||
def expandQName(self, eName, attrName, attrValue):
|
||||
bigValue = attrValue
|
||||
@@ -298,38 +390,57 @@ class NsElement(object):
|
||||
if shortNs == attrNS:
|
||||
bigValue = '%s:%s' % (longNs, attrNCName)
|
||||
break
|
||||
## print '[expandQName] input attrName = "%s" and attrValue "%s"; output = "%s"' % (attrName, attrValue, bigValue)
|
||||
return bigValue
|
||||
|
||||
class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
def __init__(self, knownTypes=None, knownNamespaces=None):
|
||||
def __init__(self, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||
self.rootelement = None
|
||||
if (knownTypes == None):
|
||||
self.knownTypes = {}
|
||||
if xmlSource == None:
|
||||
self.xmlSource = "unknown"
|
||||
else:
|
||||
self.knownTypes = knownTypes
|
||||
if (knownNamespaces == None):
|
||||
self.knownNamespaces = {}
|
||||
else:
|
||||
self.knownNamespaces = knownNamespaces
|
||||
self.xmlSource = xmlSource
|
||||
self.createGenerics = createGenerics
|
||||
self.skipper = False
|
||||
self.elementstack = []
|
||||
self.nsstack = []
|
||||
self.collectContent = None
|
||||
if (knownNamespaces == None):
|
||||
self.knownNamespaces = {}
|
||||
else:
|
||||
self.knownNamespaces = knownNamespaces
|
||||
self.reversedNamespaces = {}
|
||||
for longns, shortns in self.knownNamespaces.iteritems():
|
||||
self.reversedNamespaces[shortns] = longns
|
||||
self.knownTypes = {}
|
||||
if (knownTypes != None):
|
||||
for tag, cls in knownTypes.iteritems():
|
||||
i = tag.rfind(':')
|
||||
if i >= 0:
|
||||
shortns = tag[:i]
|
||||
tag = tag[i+1:]
|
||||
if not self.reversedNamespaces.has_key(shortns):
|
||||
errorString = 'Error unmarshalling XML document from source "%s": knownTypes specifies an unmapped short namespace "%s" for element "%s"' % (self.xmlSource, shortns, tag)
|
||||
raise UnmarshallerException(errorString)
|
||||
longns = self.reversedNamespaces[shortns]
|
||||
tag = '%s:%s' % (longns, tag)
|
||||
self.knownTypes[tag] = cls
|
||||
#printKnownTypes(self.knownTypes, 'Unmarshaller.XMLObjectFactory.__init__')
|
||||
xml.sax.handler.ContentHandler.__init__(self)
|
||||
|
||||
def appendElementStack(self, newElement, newNS):
|
||||
self.elementstack.append(newElement)
|
||||
if (newNS.isEmpty()):
|
||||
if (len(self.nsstack) > 0):
|
||||
newNS = self.nsstack[-1]
|
||||
else:
|
||||
newNS.knownTypes = self.knownTypes.copy()
|
||||
else:
|
||||
if (len(self.nsstack) > 0):
|
||||
newNS.setKnownTypes(self.knownTypes, self.knownNamespaces, self.nsstack[-1])
|
||||
else:
|
||||
newNS.setKnownTypes(self.knownTypes, self.knownNamespaces, None)
|
||||
if (len(self.nsstack) > 0):
|
||||
oldNS = self.nsstack[-1]
|
||||
if newNS.defaultNS == None:
|
||||
newNS.defaultNS = oldNS.defaultNS
|
||||
if newNS.targetNS == None:
|
||||
newNS.targetNS = oldNS.targetNS
|
||||
if len(newNS.nsMap) == 0:
|
||||
newNS.nsMap = oldNS.nsMap
|
||||
elif len(oldNS.nsMap) > 0:
|
||||
map = oldNS.nsMap.copy()
|
||||
map.update(newNS.nsMap)
|
||||
newNS.nsMap = map
|
||||
self.nsstack.append(newNS)
|
||||
return newNS
|
||||
|
||||
@@ -353,11 +464,16 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
strVal += '>'
|
||||
self.collectContent.content += strVal
|
||||
xsname = name
|
||||
if name.find(':') > -1: # Strip namespace prefixes for now until actually looking them up in xsd
|
||||
name = name[name.rfind(":") + 1:]
|
||||
i = name.rfind(':')
|
||||
if i >= 0:
|
||||
nsname = name[:i]
|
||||
name = name[i+1:]
|
||||
else:
|
||||
nsname = None
|
||||
element = Element(name, attrs.copy(), xsname=xsname)
|
||||
# if the element has namespace attributes, process them and add them to our stack
|
||||
nse = NsElement()
|
||||
objtype = None
|
||||
for k in attrs.getNames():
|
||||
if k.startswith('xmlns'):
|
||||
longNs = attrs[k]
|
||||
@@ -371,8 +487,28 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
nse.nsMap[shortNs] = longNs
|
||||
elif k == 'targetNamespace':
|
||||
nse.targetNS = attrs.getValue(k)
|
||||
elif k == 'objtype':
|
||||
objtype = attrs.getValue(k)
|
||||
nse = self.appendElementStack(element, nse)
|
||||
element.objclass = nse.knownTypes.get(xsname)
|
||||
if nsname != None:
|
||||
if nse.nsMap.has_key(nsname):
|
||||
longname = '%s:%s' % (nse.nsMap[nsname], name)
|
||||
## elif objtype == None:
|
||||
## errorString = 'Error unmarshalling XML document from source "%s": tag "%s" at line "%d", column "%d" has an undefined namespace' % (self.xmlSource, xsname, self._locator.getLineNumber(), self._locator.getColumnNumber())
|
||||
## raise UnmarshallerException(errorString)
|
||||
elif self.reversedNamespaces.has_key(nsname):
|
||||
longname = '%s:%s' % (self.reversedNamespaces[nsname], name)
|
||||
else:
|
||||
longname = xsname
|
||||
elif nse.defaultNS != None:
|
||||
longname = '%s:%s' % (nse.defaultNS, name)
|
||||
else:
|
||||
longname = name
|
||||
element.objtype = objtype
|
||||
element.objclass = self.knownTypes.get(longname)
|
||||
if element.objclass == None and len(self.knownNamespaces) == 0:
|
||||
# handles common case where tags are unqualified and knownTypes are too, but there's a defaultNS
|
||||
element.objclass = self.knownTypes.get(name)
|
||||
if (hasattr(element.objclass, "__xmlcontent__")):
|
||||
self.collectContent = element
|
||||
|
||||
@@ -387,8 +523,9 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
def endElement(self, name):
|
||||
## print "[endElement] </%s>" % name
|
||||
xsname = name
|
||||
if name.find(":") > -1: # Strip namespace prefixes for now until actually looking them up in xsd
|
||||
name = name[name.find(":") + 1:]
|
||||
i = name.rfind(':')
|
||||
if i >= 0: # Strip namespace prefixes for now until actually looking them up in xsd
|
||||
name = name[i+1:]
|
||||
if self.skipper:
|
||||
if xsname == "xs:annotation" or xsname == "xsd:annotation": # here too
|
||||
self.skipper = False
|
||||
@@ -405,34 +542,36 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
element, nse = self.popElementStack()
|
||||
if ((len(self.elementstack) > 1) and (self.elementstack[-1].getobjtype() == "None")):
|
||||
parentElement = self.elementstack[-2]
|
||||
## print "[endElement] %s: found parent with objtype==None: using its grandparent" % name
|
||||
elif (len(self.elementstack) > 0):
|
||||
parentElement = self.elementstack[-1]
|
||||
objtype = element.getobjtype()
|
||||
## print "element objtype is: ", objtype
|
||||
if (objtype == "None"):
|
||||
## print "[endElement] %s: skipping a (objtype==None) end tag" % name
|
||||
return
|
||||
constructorarglist = []
|
||||
if (len(element.content) > 0):
|
||||
strippedElementContent = element.content.strip()
|
||||
if (len(strippedElementContent) > 0):
|
||||
constructorarglist.append(element.content)
|
||||
# If the element requires an object, but none is known, use the GenericXMLObject class
|
||||
if ((element.objclass == None) and (element.attrs.get("objtype") == None) and ((len(element.attrs) > 0) or (len(element.children) > 0))):
|
||||
if self.createGenerics:
|
||||
element.objclass = GenericXMLObject
|
||||
obj = _objectfactory(objtype, constructorarglist, element.objclass)
|
||||
if element.objclass == GenericXMLObject:
|
||||
obj.setXMLAttributes(str(xsname), element.attrs, element.children, nse.nsMap, nse.defaultNS)
|
||||
complexType = getComplexType(obj)
|
||||
if (obj != None):
|
||||
if (hasattr(obj, "__xmlname__") and getattr(obj, "__xmlname__") == "sequence"):
|
||||
self.elementstack[-1].children = oldChildren
|
||||
return
|
||||
if (len(element.attrs) > 0) and not isinstance(obj, list):
|
||||
## print "[endElement] %s: element has attrs and the obj is not a list" % name
|
||||
for attrname, attr in element.attrs.items():
|
||||
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
|
||||
if attrname.startswith(XMLNS_PREFIX):
|
||||
ns = attrname[XMLNS_PREFIX_LENGTH:]
|
||||
else:
|
||||
ns = ""
|
||||
if complexType != None:
|
||||
if complexType != None or element.objclass == GenericXMLObject:
|
||||
if not hasattr(obj, "__xmlnamespaces__"):
|
||||
obj.__xmlnamespaces__ = {ns:attr}
|
||||
elif ns not in obj.__xmlnamespaces__:
|
||||
@@ -447,7 +586,6 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
xsdElement = complexType.findElement(attrname)
|
||||
if (xsdElement != None):
|
||||
type = xsdElement.type
|
||||
## print 'Unmarshalling element "%s", attribute "%s" with type "%s"' % (name, xsdElement.name, type)
|
||||
if (type != None):
|
||||
if (type == TYPE_QNAME):
|
||||
attr = nse.expandQName(name, attrname, attr)
|
||||
@@ -455,11 +593,15 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
### ToDO remove maxOccurs hack after bug 177 is fixed
|
||||
if attrname == "maxOccurs" and attr == "unbounded":
|
||||
attr = "-1"
|
||||
attr = _objectfactory(type, attr)
|
||||
try:
|
||||
attr = _objectfactory(type, attr)
|
||||
except Exception, exceptData:
|
||||
errorString = 'Error unmarshalling attribute "%s" at line %d, column %d in XML document from source "%s": %s' % (attrname, self._locator.getLineNumber(), self._locator.getColumnNumber(), self.xmlSource, str(exceptData))
|
||||
raise UnmarshallerException(errorString)
|
||||
try:
|
||||
setattrignorecase(obj, _toAttrName(obj, attrname), attr)
|
||||
except AttributeError:
|
||||
errorString = 'Error unmarshalling XML document at line %i, column %i: The object type of attribute "%s" of XML element "%s": not specified or known' % (self._locator.getLineNumber(), self._locator.getColumnNumber(), attrname, name)
|
||||
errorString = 'Error setting value of attribute "%s" at line %d, column %d in XML document from source "%s": object type of XML element "%s" is not specified or known' % (attrname, self._locator.getLineNumber(), self._locator.getColumnNumber(), self.xmlSource, name)
|
||||
raise UnmarshallerException(errorString)
|
||||
## obj.__dict__[_toAttrName(obj, attrname)] = attr
|
||||
# stuff any child attributes meant to be in a sequence via the __xmlflattensequence__
|
||||
@@ -474,14 +616,12 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
flattenDict[str(xmlnametuple)] = sequencename
|
||||
else:
|
||||
for xmlname in xmlnametuple:
|
||||
## print "[endElement]: adding flattenDict[%s] = %s" % (xmlname, sequencename)
|
||||
flattenDict[xmlname] = sequencename
|
||||
else:
|
||||
raise Exception("Invalid type for __xmlflattensequence___ : it must be a dict")
|
||||
|
||||
# reattach an object"s attributes to it
|
||||
for childname, child in element.children:
|
||||
## print "[endElement] childname is: ", childname, "; child is: ", child
|
||||
if (childname in flattenDict):
|
||||
sequencename = _toAttrName(obj, flattenDict[childname])
|
||||
if (not hasattr(obj, sequencename)):
|
||||
@@ -499,12 +639,13 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
else:
|
||||
obj[childname] = child
|
||||
else:
|
||||
## print "childname = %s, obj = %s, child = %s" % (childname, repr(obj), repr(child))
|
||||
try:
|
||||
setattrignorecase(obj, _toAttrName(obj, childname), child)
|
||||
except AttributeError:
|
||||
raise MarshallerException("Error unmarshalling child element \"%s\" of XML element \"%s\": object type not specified or known" % (childname, name))
|
||||
## obj.__dict__[_toAttrName(obj, childname)] = child
|
||||
# don't replace a good attribute value with a bad one
|
||||
childAttrName = _toAttrName(obj, childname)
|
||||
if (not hasattr(obj, childAttrName)) or (getattr(obj, childAttrName) == None) or (getattr(obj, childAttrName) == []) or (not isinstance(child, GenericXMLObject)):
|
||||
try:
|
||||
setattrignorecase(obj, childAttrName, child)
|
||||
except AttributeError:
|
||||
raise MarshallerException("Error unmarshalling child element \"%s\" of XML element \"%s\": object type not specified or known" % (childname, name))
|
||||
|
||||
if (complexType != None):
|
||||
for element in complexType.elements:
|
||||
@@ -524,7 +665,6 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
||||
if (len(self.elementstack) > 0):
|
||||
## print "[endElement] appending child with name: ", name, "; objtype: ", objtype
|
||||
parentElement.children.append((name, obj))
|
||||
## print "parentElement now has ", len(parentElement.children), " children"
|
||||
else:
|
||||
self.rootelement = obj
|
||||
|
||||
@@ -539,7 +679,12 @@ def _toAttrName(obj, name):
|
||||
break
|
||||
## if (name.startswith("__") and not name.endswith("__")):
|
||||
## name = "_%s%s" % (obj.__class__.__name__, name)
|
||||
return name
|
||||
return str(name)
|
||||
|
||||
def printKnownTypes(kt, where):
|
||||
print 'KnownTypes from %s' % (where)
|
||||
for tag, cls in kt.iteritems():
|
||||
print '%s => %s' % (tag, str(cls))
|
||||
|
||||
__typeMappingXsdToLang = {
|
||||
"string": "str",
|
||||
@@ -569,7 +714,7 @@ def xsdToLangType(xsdType):
|
||||
if xsdType.startswith(XMLSCHEMA_XSD_URL):
|
||||
xsdType = xsdType[len(XMLSCHEMA_XSD_URL)+1:]
|
||||
elif xsdType.startswith(AG_URL):
|
||||
xsdType = xsdType[len(AG_URL)+1:]
|
||||
xsdType = xsdType[len(AG_URL)+1:]
|
||||
langType = __typeMappingXsdToLang.get(xsdType)
|
||||
if (langType == None):
|
||||
raise Exception("Unknown xsd type %s" % xsdType)
|
||||
@@ -588,8 +733,11 @@ def _getXmlValue(langValue):
|
||||
else:
|
||||
return str(langValue)
|
||||
|
||||
def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
||||
objectfactory = XMLObjectFactory(knownTypes, knownNamespaces)
|
||||
def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||
objectfactory = XMLObjectFactory(knownTypes, knownNamespaces, xmlSource, createGenerics)
|
||||
# on Linux, pyXML's sax.parseString fails when passed unicode
|
||||
if (not sysutils.isWindows()):
|
||||
xmlstr = str(xmlstr)
|
||||
try:
|
||||
xml.sax.parseString(xmlstr, objectfactory)
|
||||
except xml.sax.SAXParseException, errorData:
|
||||
@@ -600,17 +748,19 @@ def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
||||
return objectfactory.getRootObject()
|
||||
|
||||
def marshal(obj, elementName=None, prettyPrint=False, marshalType=True, indent=0, knownTypes=None, knownNamespaces=None, encoding=-1):
|
||||
## print '[marshal] entered with elementName = "%s"' % (elementName)
|
||||
worker = XMLMarshalWorker(prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces)
|
||||
if obj != None and hasattr(obj, '__xmldeepexclude__'):
|
||||
worker.xmldeepexclude = obj.__xmldeepexclude__
|
||||
xmlstr = "".join(worker._marshal(obj, elementName, indent=indent))
|
||||
if (isinstance(encoding, basestring)):
|
||||
return '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr.encode(encoding))
|
||||
elif (encoding == None):
|
||||
aglogging.info(xmlMarshallerLogger, "marshal produced string of type %s", type(xmlstr))
|
||||
if (encoding == None):
|
||||
return xmlstr
|
||||
else:
|
||||
return '<?xml version="1.0" encoding="%s"?>\n%s' % (sys.getdefaultencoding(), xmlstr)
|
||||
if (not isinstance(encoding, basestring)):
|
||||
encoding = sys.getdefaultencoding()
|
||||
if (not isinstance(xmlstr, unicode)):
|
||||
xmlstr = xmlstr.decode()
|
||||
xmlstr = u'<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr)
|
||||
return xmlstr.encode(encoding)
|
||||
|
||||
class XMLMarshalWorker(object):
|
||||
def __init__(self, marshalType=True, prettyPrint=False, knownTypes=None, knownNamespaces=None):
|
||||
@@ -695,7 +845,7 @@ class XMLMarshalWorker(object):
|
||||
newNS.prefix = self.nsstack[-1].prefix
|
||||
else:
|
||||
newNS.prefix = ''
|
||||
if hasattr(obj, "__xmldefaultnamespace__"):
|
||||
if obj != None and hasattr(obj, "__xmldefaultnamespace__"):
|
||||
longPrefixNS = getattr(obj, "__xmldefaultnamespace__")
|
||||
if longPrefixNS == defaultLongNS:
|
||||
newNS.prefix = ''
|
||||
@@ -705,13 +855,12 @@ class XMLMarshalWorker(object):
|
||||
if v == longPrefixNS:
|
||||
newNS.prefix = k + ':'
|
||||
break;
|
||||
## print '[appendNSStack] found longPrefixNS in nameSpaces = "%s"' % (newNS.prefix)
|
||||
except:
|
||||
if (longPrefixNS in asDict(self.knownNamespaces)):
|
||||
newNS.prefix = self.knownNamespaces[longPrefixNS] + ':'
|
||||
else:
|
||||
raise MarshallerException('Error marshalling __xmldefaultnamespace__ ("%s") not defined in namespace stack' % (longPrefixNS))
|
||||
if hasattr(obj, "targetNamespace"):
|
||||
if obj != None and hasattr(obj, "targetNamespace"):
|
||||
newNS.targetNS = obj.targetNamespace
|
||||
elif len(self.nsstack) > 0:
|
||||
newNS.targetNS = self.nsstack[-1].targetNS
|
||||
@@ -749,9 +898,11 @@ class XMLMarshalWorker(object):
|
||||
|
||||
def _marshal(self, obj, elementName=None, nameSpacePrefix="", indent=0):
|
||||
if (obj != None):
|
||||
xmlMarshallerLogger.debug("--> _marshal: elementName=%s%s, type=%s, obj=%s, indent=%d" % (nameSpacePrefix, elementName, type(obj), str(obj), indent))
|
||||
aglogging.debug(xmlMarshallerLogger, "--> _marshal: elementName=%s%s, type=%s, obj=%s, indent=%d", nameSpacePrefix, elementName, type(obj), str(obj), indent)
|
||||
else:
|
||||
xmlMarshallerLogger.debug("--> _marshal: elementName=%s%s, obj is None, indent=%d" % (nameSpacePrefix, elementName, indent))
|
||||
aglogging.debug(xmlMarshallerLogger, "--> _marshal: elementName=%s%s, obj is None, indent=%d", nameSpacePrefix, elementName, indent)
|
||||
if ((obj != None) and (hasattr(obj, 'preMarshal'))):
|
||||
obj.preMarshal()
|
||||
excludeAttrs = []
|
||||
excludeAttrs.extend(self.xmldeepexclude)
|
||||
if hasattr(obj, "__xmlexclude__"):
|
||||
@@ -768,8 +919,8 @@ class XMLMarshalWorker(object):
|
||||
newline = ""
|
||||
increment = 0
|
||||
## Determine the XML element name. If it isn"t specified in the
|
||||
## parameter list, look for it in the __xmlname__ Lang
|
||||
## attribute, else use the default generic BASETYPE_ELEMENT_NAME.
|
||||
## parameter list, look for it in the __xmlname__ attribute,
|
||||
## else use the default generic BASETYPE_ELEMENT_NAME.
|
||||
nameSpaceAttrs = self.appendNSStack(obj)
|
||||
nameSpacePrefix = self.getNSPrefix()
|
||||
if not elementName:
|
||||
@@ -779,13 +930,15 @@ class XMLMarshalWorker(object):
|
||||
elementName = nameSpacePrefix + BASETYPE_ELEMENT_NAME
|
||||
else:
|
||||
elementName = nameSpacePrefix + elementName
|
||||
## print '[XMLMarshalWorker._marshal] elementName "%s"; nameSpaceAttrs is "%s"' % (elementName, nameSpaceAttrs)
|
||||
|
||||
if (hasattr(obj, "__xmlsequencer__")) and (obj.__xmlsequencer__ != None):
|
||||
if (XMLSCHEMA_XSD_URL in self.nsstack[-1].nameSpaces.values()):
|
||||
for kShort, vLong in self.nsstack[-1].nameSpaces.iteritems():
|
||||
if vLong == XMLSCHEMA_XSD_URL:
|
||||
xsdPrefix = kShort + ':'
|
||||
if kShort != DEFAULT_NAMESPACE_KEY:
|
||||
xsdPrefix = kShort + ':'
|
||||
else:
|
||||
xsdPrefix = ''
|
||||
break
|
||||
else:
|
||||
xsdPrefix = 'xs:'
|
||||
@@ -793,7 +946,6 @@ class XMLMarshalWorker(object):
|
||||
else:
|
||||
elementAdd = None
|
||||
|
||||
## print "marshal: entered with elementName: ", elementName
|
||||
members_to_skip = []
|
||||
## Add more members_to_skip based on ones the user has selected
|
||||
## via the __xmlexclude__ and __xmldeepexclude__ attributes.
|
||||
@@ -806,7 +958,6 @@ class XMLMarshalWorker(object):
|
||||
xmlattributes = obj.__xmlattributes__
|
||||
members_to_skip.extend(xmlattributes)
|
||||
for attr in xmlattributes:
|
||||
## print 'Processing element "%s"; attribute "%s"' % (elementName, attr)
|
||||
internalAttrName = attr
|
||||
ifDefPy()
|
||||
if (attr.startswith("__") and not attr.endswith("__")):
|
||||
@@ -814,7 +965,6 @@ class XMLMarshalWorker(object):
|
||||
endIfDef()
|
||||
# Fail silently if a python attribute is specified to be
|
||||
# an XML attribute but is missing.
|
||||
## print "marshal: processing attribute ", internalAttrName
|
||||
attrNameSpacePrefix = ""
|
||||
if hasattr(obj, "__xmlattrnamespaces__"):
|
||||
for nameSpaceKey, nameSpaceAttributes in getattr(obj, "__xmlattrnamespaces__").iteritems():
|
||||
@@ -856,8 +1006,7 @@ class XMLMarshalWorker(object):
|
||||
else:
|
||||
value = objutils.toDiffableRepr(value)
|
||||
|
||||
objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, saxutils.escape(value))
|
||||
## print "marshal: new objattrs is: ", objattrs
|
||||
objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, utillang.escape(value))
|
||||
if (obj == None):
|
||||
xmlString = [""]
|
||||
elif isinstance(obj, bool):
|
||||
@@ -873,9 +1022,18 @@ class XMLMarshalWorker(object):
|
||||
objTypeStr = self._genObjTypeStr("float")
|
||||
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||
elif isinstance(obj, unicode): # have to check before basestring - unicode is instance of base string
|
||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj.encode()), elementName, newline)]
|
||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, utillang.escape(obj.encode()), elementName, newline)]
|
||||
elif isinstance(obj, basestring):
|
||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj), elementName, newline)]
|
||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, utillang.escape(obj), elementName, newline)]
|
||||
elif isinstance(obj, datetime.datetime):
|
||||
objTypeStr = self._genObjTypeStr("datetime")
|
||||
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||
elif isinstance(obj, datetime.date):
|
||||
objTypeStr = self._genObjTypeStr("date")
|
||||
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||
elif isinstance(obj, datetime.time):
|
||||
objTypeStr = self._genObjTypeStr("time")
|
||||
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||
elif isinstance(obj, list):
|
||||
if len(obj) < 1:
|
||||
xmlString = ""
|
||||
@@ -910,13 +1068,15 @@ class XMLMarshalWorker(object):
|
||||
elif hasattr(obj, "__xmlcontent__"):
|
||||
contentValue = getattr(obj, obj.__xmlcontent__)
|
||||
if contentValue == None:
|
||||
contentValue = ''
|
||||
xmlString = ["%s<%s%s%s/>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, newline)]
|
||||
else:
|
||||
contentValue = saxutils.escape(contentValue)
|
||||
xmlString = ["%s<%s%s%s>%s</%s>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, contentValue, elementName, newline)]
|
||||
contentValue = utillang.escape(contentValue)
|
||||
xmlString = ["%s<%s%s%s>%s</%s>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, contentValue, elementName, newline)]
|
||||
else:
|
||||
# Only add the objtype if the element tag is unknown to us.
|
||||
if (self.isKnownType(elementName) == True):
|
||||
if (isinstance(obj, GenericXMLObject)):
|
||||
objTypeStr = ""
|
||||
elif (self.isKnownType(elementName) == True):
|
||||
objTypeStr = ""
|
||||
else:
|
||||
objTypeStr = self._genObjTypeStr("%s.%s" % (obj.__class__.__module__, className))
|
||||
@@ -929,7 +1089,7 @@ class XMLMarshalWorker(object):
|
||||
if hasattr(obj, "__xmlbody__"):
|
||||
xmlbody = getattr(obj, obj.__xmlbody__)
|
||||
if xmlbody != None:
|
||||
xmlMemberString.append(xmlbody)
|
||||
xmlMemberString.append(utillang.escape(xmlbody))
|
||||
else:
|
||||
if hasattr(obj, "__xmlattrgroups__"):
|
||||
attrGroups = obj.__xmlattrgroups__.copy()
|
||||
@@ -975,21 +1135,17 @@ class XMLMarshalWorker(object):
|
||||
xmlname = None
|
||||
if (len(xmlnametuple) == 1):
|
||||
xmlname = xmlnametuple[0]
|
||||
## ix = 0
|
||||
if not isinstance(value, (list, tuple)):
|
||||
value = [value]
|
||||
for seqitem in value:
|
||||
## xmlname = xmlnametuple[ix]
|
||||
## ix += 1
|
||||
## if (ix >= len(xmlnametuple)):
|
||||
## ix = 0
|
||||
xmlMemberString.extend(self._marshal(seqitem, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
||||
else:
|
||||
if (hasattr(obj, "__xmlrename__") and name in asDict(obj.__xmlrename__)):
|
||||
xmlname = obj.__xmlrename__[name]
|
||||
else:
|
||||
xmlname = name
|
||||
xmlMemberString.extend(self._marshal(value, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
||||
if (value != None):
|
||||
xmlMemberString.extend(self._marshal(value, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
||||
if (eName != "__nogroup__"):
|
||||
xmlMemberString.append("%s</%s>%s" % (prefix, eName, newline))
|
||||
prefix = prefix[:-increment]
|
||||
@@ -1022,8 +1178,8 @@ class XMLMarshalWorker(object):
|
||||
xmlString.append("><![CDATA[%s]]></%s>%s" % (cdataContent, elementName, newline))
|
||||
else:
|
||||
xmlString.append("/>%s" % newline)
|
||||
## return xmlString
|
||||
xmlMarshallerLogger.debug("<-- _marshal: %s" % str(xmlString))
|
||||
if aglogging.isEnabledForDebug(xmlMarshallerLogger):
|
||||
aglogging.debug(xmlMarshallerLogger, "<-- _marshal: %s", objutils.toDiffableString(xmlString))
|
||||
#print "<-- _marshal: %s" % str(xmlString)
|
||||
self.popNSStack()
|
||||
return xmlString
|
||||
|
Reference in New Issue
Block a user