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

📄 xmlmarshaller.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 4 页
字号:
        ## 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:
            if hasattr(obj, "__xmlname__"):
                elementName = nameSpacePrefix + obj.__xmlname__
            else:
                elementName = nameSpacePrefix + BASETYPE_ELEMENT_NAME
        else:
            elementName = nameSpacePrefix + elementName
    
        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:
                        if kShort != DEFAULT_NAMESPACE_KEY:
                            xsdPrefix = kShort + ':'
                        else:
                            xsdPrefix = ''
                        break
            else:
                xsdPrefix = 'xs:'
            elementAdd = xsdPrefix + obj.__xmlsequencer__
        else:
            elementAdd = None
                   
        members_to_skip = []
        ## Add more members_to_skip based on ones the user has selected
        ## via the __xmlexclude__ and __xmldeepexclude__ attributes.
        members_to_skip.extend(excludeAttrs)
        # Marshal the attributes that are selected to be XML attributes.
        objattrs = ""
        className = ag_className(obj)
        classNamePrefix = "_" + className
        if hasattr(obj, "__xmlattributes__"):
            xmlattributes = obj.__xmlattributes__
            members_to_skip.extend(xmlattributes)
            for attr in xmlattributes:
                internalAttrName = attr
                ifDefPy()
                if (attr.startswith("__") and not attr.endswith("__")): 
                    internalAttrName = classNamePrefix + attr
                endIfDef()
                # Fail silently if a python attribute is specified to be
                # an XML attribute but is missing.
                attrNameSpacePrefix = ""
                if hasattr(obj, "__xmlattrnamespaces__"):
                    for nameSpaceKey, nameSpaceAttributes in getattr(obj, "__xmlattrnamespaces__").iteritems():
                        if nameSpaceKey == nameSpacePrefix[:-1]: # Don't need to specify attribute namespace if it is the same as its element
                            continue
                        if attr in nameSpaceAttributes:
                            attrNameSpacePrefix = nameSpaceKey + ":"
                            break
                attrs = obj.__dict__
                value = attrs.get(internalAttrName)
                if (hasattr(obj, "__xmlrename__") and attr in asDict(obj.__xmlrename__)):
                    attr = obj.__xmlrename__[attr]
                xsdElement = None
                complexType = getComplexType(obj)
                if (complexType != None):
                    xsdElement = complexType.findElement(attr)
                if (xsdElement != None):
                    default = xsdElement.default
                    if (default != None):
                        if ((default == value) or (default == _getXmlValue(value))):
                            continue
                    else:
                        if (value == None):
                            continue
                        elif xsdElement.type == TYPE_QNAME:
                            value = self.contractQName(value, obj, attr)
                elif value == None:
                    continue
    
                # ToDO remove maxOccurs hack after bug 177 is fixed
                if attr == "maxOccurs" and value == -1:
                    value = "unbounded"
    
                if isinstance(value, bool):
                   if value == True:
                       value = "true"
                   else:
                       value = "false"
                else:
                    value = objutils.toDiffableRepr(value)
    
                objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, utillang.escape(value))
        if (obj == None):
            xmlString = [""]
        elif isinstance(obj, bool):
            objTypeStr = self._genObjTypeStr("bool")
            xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, obj, elementName, newline)]
        elif isinstance(obj, int):
            objTypeStr = self._genObjTypeStr("int")
            xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
        elif isinstance(obj, long):
            objTypeStr = self._genObjTypeStr("long")
            xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
        elif isinstance(obj, float):
            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, utillang.escape(obj.encode()), elementName, newline)]
        elif isinstance(obj, basestring):
            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 = ""
            else:
                objTypeStr = self._genObjTypeStr("list")
                xmlString = ['%s<%s%s>%s' % (prefix, elementName, objTypeStr, newline)]
                for item in obj:
                    xmlString.extend(self._marshal(item, indent=indent+increment))
                xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
        elif isinstance(obj, tuple):
            if len(obj) < 1:
                xmlString = ""
            else:
                objTypeStr = self._genObjTypeStr("list")
                xmlString = ['%s<%s%s mutable="false">%s' % (prefix, elementName, objTypeStr, newline)]
                for item in obj:
                    xmlString.extend(self._marshal(item, indent=indent+increment))
                xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
        elif isinstance(obj, dict):
            objTypeStr = self._genObjTypeStr("dict")
            xmlString = ['%s<%s%s>%s' % (prefix, elementName, objTypeStr, newline)]
            subprefix = prefix + " "*increment
            subindent = indent + 2*increment
            keys = obj.keys()
            keys.sort()
            for key in keys:
                xmlString.append("%s<%s>%s" % (subprefix, DICT_ITEM_NAME, newline))
                xmlString.extend(self._marshal(key, elementName=DICT_ITEM_KEY_NAME, indent=subindent))
                xmlString.extend(self._marshal(obj[key], elementName=DICT_ITEM_VALUE_NAME, indent=subindent))
                xmlString.append("%s</%s>%s" % (subprefix, DICT_ITEM_NAME, newline))
            xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
        elif hasattr(obj, "__xmlcontent__"):
            contentValue = getattr(obj, obj.__xmlcontent__)
            if contentValue == None: 
                xmlString = ["%s<%s%s%s/>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, newline)]        
            else:
                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 (isinstance(obj, GenericXMLObject)):
                objTypeStr = ""
            elif (self.isKnownType(elementName) == True):
                objTypeStr = ""
            else:
                objTypeStr = self._genObjTypeStr("%s.%s" % (obj.__class__.__module__, className))
            xmlString = ['%s<%s%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs, objTypeStr)]
            # get the member, value pairs for the object, filtering out the types we don"t support
            if (elementAdd != None):
                prefix += increment*" "
                indent += increment
            xmlMemberString = []
            if hasattr(obj, "__xmlbody__"):
                xmlbody = getattr(obj, obj.__xmlbody__)
                if xmlbody != None:
                    xmlMemberString.append(utillang.escape(xmlbody))
            else:
                if hasattr(obj, "__xmlattrgroups__"):
                    attrGroups = obj.__xmlattrgroups__.copy()
                    if (not isinstance(attrGroups, dict)):
                        raise "__xmlattrgroups__ is not a dict, but must be"
                    for n in attrGroups.iterkeys():
                        members_to_skip.extend(attrGroups[n])
                else:
                    attrGroups = {}
                # add the list of all attributes to attrGroups
                eList = obj.__dict__.keys()    
                eList.sort()
                attrGroups["__nogroup__"] = eList
                
                for eName, eList in attrGroups.iteritems():
                    if (eName != "__nogroup__"):
                        prefix += increment*" "
                        indent += increment
                        objTypeStr = self._genObjTypeStr("None")
                        xmlMemberString.append('%s<%s%s>%s' % (prefix, eName, objTypeStr, newline))
                    for name in eList:
                        value = obj.__dict__[name]
                        if eName == "__nogroup__" and name in members_to_skip: continue
                        if name.startswith("__") and name.endswith("__"): continue
                        if (hasattr(obj, "__xmlcdatacontent__") and (obj.__xmlcdatacontent__ == name)):
                            continue
                        subElementNameSpacePrefix = nameSpacePrefix
                        if hasattr(obj, "__xmlattrnamespaces__"):
                            for nameSpaceKey, nameSpaceValues in getattr(obj, "__xmlattrnamespaces__").iteritems():
                                if name in nameSpaceValues:
                                    subElementNameSpacePrefix = nameSpaceKey + ":"
                                    break
                        # handle sequences listed in __xmlflattensequence__
                        # specially: instead of listing the contained items inside
                        # of a separate list, as God intended, list them inside
                        # the object containing the sequence.
                        if (hasattr(obj, "__xmlflattensequence__") and (value != None) and (name in asDict(obj.__xmlflattensequence__))):
                            xmlnametuple = obj.__xmlflattensequence__[name]
                            if (xmlnametuple == None):
                                xmlnametuple = [name]
                            elif (not isinstance(xmlnametuple, (tuple,list))):
                                xmlnametuple = [str(xmlnametuple)]
                            xmlname = None
                            if (len(xmlnametuple) == 1):
                                xmlname = xmlnametuple[0]
                            if not isinstance(value, (list, tuple)):
                              value = [value]
                            for seqitem in value:
                                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
                            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]
                        indent -= increment
    
            # if we have nested elements, add them here, otherwise close the element tag immediately.
            newList = []
            for s in xmlMemberString:
                if (len(s) > 0): newList.append(s)
            xmlMemberString = newList
            if len(xmlMemberString) > 0:
                xmlString.append(">")
                if hasattr(obj, "__xmlbody__"):
                    xmlString.extend(xmlMemberString)
                    xmlString.append("</%s>%s" % (elementName, newline))
                else:
                    xmlString.append(newline)
                    if (elementAdd != None):
                        xmlString.append("%s<%s>%s" % (prefix, elementAdd, newline))
                    xmlString.extend(xmlMemberString)
                    if (elementAdd != None):
                        xmlString.append("%s</%s>%s" % (prefix, elementAdd, newline))
                        prefix = prefix[:-increment]
                        indent -= increment
                    xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
            else:
                if hasattr(obj, "__xmlcdatacontent__"):
                    cdataAttr = obj.__xmlcdatacontent__
                    cdataContent = obj.__dict__[cdataAttr]
                    xmlString.append("><![CDATA[%s]]></%s>%s" % (cdataContent, elementName, newline))
                else:
                    xmlString.append("/>%s" % newline)
        if aglogging.isEnabledForDebug(xmlMarshallerLogger):
            aglogging.debug(xmlMarshallerLogger, "<-- _marshal: %s", objutils.toDiffableString(xmlString))
        #print "<-- _marshal: %s" % str(xmlString)
        self.popNSStack()
        return xmlString

# A simple test, to be executed when the xmlmarshaller is run standalone
class MarshallerPerson:
    __xmlname__ = "person"
    __xmlexclude__ = ["fabulousness",]
    __xmlattributes__ = ("nonSmoker",)
    __xmlrename__ = {"_phoneNumber": "telephone"}
    __xmlflattensequence__ = {"favoriteWords": ("vocabulary",)}
    __xmlattrgroups__ = {"name": ["firstName", "lastName"], "address": ["addressLine1", "city", "state", "zip"]}

    def setPerson(self):
        self.firstName = "Albert"
        self.lastName = "Camus"
        self.addressLine1 = "23 Absurd St."
        self.city = "Ennui"
        self.state = "MO"
        self.zip = "54321"
        self._phoneNumber = "808-303-2323"
        self.favoriteWords = ["angst", "ennui", "existence"]
        self.phobias = ["war", "tuberculosis", "cars"]
        self.weight = 150
        self.fabulousness = "tres tres"
        self.nonSmoker = False

if isMain(__name__):
    p1 = MarshallerPerson()
    p1.setPerson() 
    xmlP1 = marshal(p1, prettyPrint=True, encoding="utf-8")        
    print "\n########################"
    print   "# testPerson test case #"
    print   "########################"
    print xmlP1
    p2 = unmarshal(xmlP1)
    xmlP2 = marshal(p2, prettyPrint=True, encoding="utf-8")
    if xmlP1 == xmlP2:
        print "Success: repeated marshalling yields identical results"
    else:
        print "Failure: repeated marshalling yields different results"
        print xmlP2

⌨️ 快捷键说明

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