⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlmarshaller.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 4 页
字号:
#----------------------------------------------------------------------------
# Name:         xmlmarshaller.py
# Purpose:
#
# Authors:      John Spurling, Joel Hare, Jeff Norton, Alan Mullendore
#
# Created:      7/28/04
# CVS-ID:       $Id: xmlmarshaller.py,v 1.7 2006/04/20 06:25:50 RD Exp $
# Copyright:    (c) 2004-2005 ActiveGrid, Inc.
# License:      wxWindows License
#----------------------------------------------------------------------------
import sys
from types import *
from activegrid.util.lang import *
import logging
ifDefPy()
import xml.sax
import xml.sax.handler
import xml.sax.saxutils
import datetime
endIfDef()
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:

name: __xmlname__
type: string
description: the name of the xml element for the marshalled object

name: __xmlattributes__
type: tuple or list
description: the name(s) of the Lang string attribute(s) to be
marshalled as xml attributes instead of nested xml elements. currently
these can only be strings since there"s not a way to get the type
information back when unmarshalling.

name: __xmlexclude__
type: tuple or list
description: the name(s) of the lang attribute(s) to skip when
marshalling.

name: __xmlrename__
type: dict
description: describes an alternate Lang <-> XML name mapping.  
Normally the name mapping is the identity function.  __xmlrename__
overrides that.  The keys are the Lang names, the values are their
associated XML names.

name: __xmlflattensequence__
type: dict, tuple, or list
description: the name(s) of the Lang sequence attribute(s) whose
items are to be marshalled as a series of xml elements (with an
optional keyword argument that specifies the element name to use) as
opposed to containing them in a separate sequence element, e.g.:

myseq = (1, 2)
<!-- normal way of marshalling -->
<myseq>
  <item objtype="int">1</item>
  <item objtype="int">2</item>
</myseq>
<!-- with __xmlflattensequence__ set to {"myseq": "squish"} -->
<squish objtype="int">1</squish>
<squish objtype="int">2</squish>

name: __xmlnamespaces__
type: dict
description: a dict of the namespaces that the object uses.  Each item
in the dict should consist of a prefix,url combination where the key is
the prefix and url is the value, e.g.:

__xmlnamespaces__ = { "xsd":"http://www.w3c.org/foo.xsd" }

name: __xmldefaultnamespace__
type: String
description: the prefix of a namespace defined in __xmlnamespaces__ that
should be used as the default namespace for the object.

name: __xmlattrnamespaces__
type: dict
description: a dict assigning the Lang object"s attributes to the namespaces
defined in __xmlnamespaces__.  Each item in the dict should consist of a
prefix,attributeList combination where the key is the prefix and the value is
a list of the Lang attribute names.  e.g.:

__xmlattrnamespaces__ = { "ag":["firstName", "lastName", "addressLine1", "city"] }

name: __xmlattrgroups__
type: dict
description: a dict specifying groups of attributes to be wrapped in an enclosing tag.
The key is the name of the enclosing tag; the value is a list of attributes to include
within it. e.g.

__xmlattrgroups__ = {"name": ["firstName", "lastName"], "address": ["addressLine1", "city", "state", "zip"]}

name: __xmlcdatacontent__
type: string
description: value is the name of a string attribute that should be assigned CDATA content from the
source document and that should be marshalled as CDATA.

__xmlcdatacontent__ = "messyContent"

"""

global xmlMarshallerLogger
xmlMarshallerLogger = logging.getLogger("activegrid.util.xmlmarshaller.marshal")
# INFO  : low-level info
# DEBUG : debugging info

################################################################################
#
# module exceptions
#
################################################################################

class Error(Exception):
    """Base class for errors in this module."""
    pass

class UnhandledTypeException(Error):
    """Exception raised when attempting to marshal an unsupported
    type.
    """
    def __init__(self, typename):
        self.typename = typename
    def __str__(self):
        return "%s is not supported for marshalling." % str(self.typename)

class XMLAttributeIsNotStringType(Error):
    """Exception raised when an object"s attribute is specified to be
    marshalled as an XML attribute of the enclosing object instead of
    a nested element.
    """
    def __init__(self, attrname, typename):
        self.attrname = attrname
        self.typename = typename
    def __str__(self):
        return """%s was set to be marshalled as an XML attribute
        instead of a nested element, but the object"s type is %s, not
        string.""" % (self.attrname, self.typename)

class MarshallerException(Exception):
    pass

class UnmarshallerException(Exception):
    pass 

################################################################################
#
# constants and such
#
################################################################################

XMLNS = "xmlns"
XMLNS_PREFIX = XMLNS + ":"
XMLNS_PREFIX_LENGTH = len(XMLNS_PREFIX)
DEFAULT_NAMESPACE_KEY = "__DEFAULTNS__"
TYPE_QNAME = "QName"
XMLSCHEMA_XSD_URL = "http://www.w3.org/2001/XMLSchema"
AG_URL = "http://www.activegrid.com/ag.xsd"

BASETYPE_ELEMENT_NAME = "item"
DICT_ITEM_NAME = "qqDictItem"
DICT_ITEM_KEY_NAME = "key"
DICT_ITEM_VALUE_NAME = "value"

# This list doesn"t seem to be used.
#   Internal documentation or useless? You make the call!
##MEMBERS_TO_SKIP = ("__module__", "__doc__", "__xmlname__", "__xmlattributes__",
##                   "__xmlexclude__", "__xmlflattensequence__", "__xmlnamespaces__",
##                   "__xmldefaultnamespace__", "__xmlattrnamespaces__",
##                   "__xmlattrgroups__")

################################################################################
#
# classes and functions
#
################################################################################

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__:
            if attr.lower() == namelow:
                object.__dict__[attr] = value
                return
    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(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])
            else:
                obj = objclass(*objargs)
        else:
            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
        self.attrs = attrs
        self.content = ""
        self.children = []
        self.objclass = None
        self.xsname = xsname
        self.objtype = None
        
    def getobjtype(self):
#        objtype = self.attrs.get("objtype")
        objtype = self.objtype
        if (objtype == None):
            if (len(self.children) > 0):
                objtype = "dict"
            else:
                objtype = "str"
        return objtype

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -