Commits

Anonymous committed 80b1081

fix elementFormDefault=qulified/unqualified

Comments (0)

Files changed (4)

                 setattr(p, name, val)
 
         #set default ns to save space
-        etree.register_namespace("", xmlnamespace.get_ns(self.name))
+        #this does not work with xml qualified/unqualified, need a hack
+        #etree.register_namespace("", xmlnamespace.get_ns(self.name))
         #the real conversion is done by ComplexType
+        #messages always refer to a top level element => qualified
         p.to_xml(kw["_body"], "{%s}%s" %(p._namespace, p.__class__.__name__))
 
     def from_xml(self, body, header = None):
             self.schema - the root node of the schema
             self.tns - target namespace
             self.imported - a list of parsers for imported schemas
+            self.qualified - value of elementFormDefault, used
+                             for handling namespaces
 
             Parameters
             ----------
         #set schema parameters
         self.schema = root
         self.tns = self.schema.get("targetNamespace", "")
+        self.qualified = self.schema.get("elementFormDefault", 0)
+        if self.qualified == "qualified":
+            self.qualified = 1
 
         #find and initialize imported ones
         self.imported = [] 
             name = el.get("name", None)
             if name is not None: #consider an exception
                 name = "{%s}%s" %(self.tns, name)
+                el.set("qualified", self.qualified)
                 types[name] = el
 
         for el in elements:
             name = el.get("name", None)
             if name is not None:
                 name = "{%s}%s" %(self.tns, name)
+                el.set("qualified", self.qualified)
                 if not(types.has_key(name)):
                     types[name] = el
 
         #simpleType.restriction - e.g. string enumeration
         if element.tag ==  "{%s}element" %xmlnamespace.NS_XSD:
             if len(element)>0:
+                element[0].set("qualified", element.get("qualified", 0))
                 element = element[0]
             else:
                 type = element.get("type", None)
             types : dictionary class name -> Python class
                 The result is appended here.
         """
+        qualified = element.get("qualified", 0)
         #decide if we have a parent and first create that
         parents = []
         exts = element.findall("./{%s}complexContent/{%s}extension" %(xmlnamespace.NS_XSD, xmlnamespace.NS_XSD))
                 break
 
         #collect children
+        cls_ns = xmlnamespace.get_ns(name)
         children = []
         if seq is not None:
             for s in seq:
                 #iterate over sequence, do not consider in place defs
                 ref = s.get("ref", None) #reference to another element
                 if ref is not None:
+                    # can there be a reference to a local element?
+                    #I assume not => always qualified
                     type_name = ref
-                    child_name = xmlnamespace.get_local_name(ref)
+                    #child_name = xmlnamespace.get_local_name(ref)
+                    child_name = ref #name is qualified by the target, is it correct?
                 else:
                     type_name = s.get('type', None)
                     child_name = s.get('name', 'unknown')
                 maxOccurs = s.get('maxOccurs', 1)
                 if maxOccurs != 'unbounded':
                     maxOccurs = int(maxOccurs)
+                #child name is qualified as required, i.e. it is a full name
+                full_child_name = child_name
+                child_name = xmlnamespace.get_local_name(child_name) #class member names!
+                if qualified and full_child_name.find("}") == -1:
+                    full_child_name = "{%s}%s" %(cls_ns, full_child_name)
                 children.append({ "name":child_name, 'type' : type,
-                                 'min' : minOccurs, 'max' : maxOccurs})
+                                 'min' : minOccurs, 'max' : maxOccurs,
+                                 "fullname": full_child_name})
         #get doc
         doc = XMLSchemaParser.get_doc(element)
 
         #I choose to give short names to classes, i.e. without
         # a namespace, even though Python can manage full names as well
         cls_name = xmlnamespace.get_local_name(name)
-        cls_ns = xmlnamespace.get_ns(name)
         cls = xmltypes.ComplexTypeMeta(cls_name, parents,
                                   {"_children":children, "__doc__":doc,
                                    "_namespace":cls_ns})
         #this level element
         element = etree.SubElement(parent, name)
 
-        #namespace for future naming
-        if self._namespace:
-            ns = "{" + self._namespace + "}"
-        else:
-            ns = ''
         #add all children to the current level
         #note that children include also base classes, as they are propagated by
         #the metaclass below
         for child in self._children:
             child_name = child["name"]
+            full_child_name = child["fullname"]
             #get the value of the argument
             val = getattr(self, child_name, None)
 
                 continue #only nillables can get so far
 
             #conversion
-            full_name = ns + child_name #name with namespace
             for single in val:
                 if not(hasattr(single, "to_xml")):
                     single = child['type'](single)
-                single.to_xml(element, full_name)
+                single.to_xml(element, full_child_name)
                 if child["type"] is XMLAny:
                     #append type information
                     element[-1].set("{%s}type" %xmlnamespace.NS_XSI, 
             _children attribute must be present in attributes. It describes
             the arguments to be present in the new type. The he
             _children argument must be a list of the form:
-            [{'name':'arg1', 'min':1, 'max':1, 'type':ClassType}, ...]
+            [{'name':'arg1', 'min':1, 'max':1, 'type':ClassType, "fullname":"name with ns"}, ...]
+            Here fullname is used for serialization and must be qualified properly.
 
             Parameters
             ----------

tests/test_xmltypes_complex.py

 
 Address = ComplexTypeMeta('Address', (), {
                 "_children":[
-                        {'name':"street", "type":XMLString, "min":1, "max": 1},
-                        {'name':"city", "type":XMLString, "min":1, "max": 1},
-                        {'name':"zip", "type":XMLInteger, "min":1, "max": 1},
-                        {'name':"since", "type":XMLDateTime, "min":0, "max": 1},
-                        {'name':"lattitude", "type":XMLDouble, "min":1, "max": 1},
-                        {'name':"longitude", "type":XMLDouble, "min":1, "max": 1},
+                    {'name':"street", "type":XMLString, "min":1, "max": 1, "fullname":"street"},
+                    {'name':"city", "type":XMLString, "min":1, "max": 1, "fullname":"city"},
+                    {'name':"zip", "type":XMLInteger, "min":1, "max": 1,"fullname":"zip"},
+                    {'name':"since", "type":XMLDateTime, "min":0, "max": 1, "fullname":"since"},
+                    {'name':"lattitude", "type":XMLDouble, "min":1, "max": 1, "fullname":"lattitude"},
+                    {'name':"longitude", "type":XMLDouble, "min":1, "max": 1, "fullname":"longitude"},
                         ], "__doc__": "an address info"})
 Person = ComplexTypeMeta('Person', (), {
                 "_children":[
-                        {'name':"name", "type":XMLString, "min":0, "max": 1},
-                        {'name':"birthdate", "type":XMLDateTime, "min":0, "max": 1},
-                        {'name':"age", "type":XMLInteger, "min":0, "max": 1},
-                        {'name':"addresses", "type":Address, "min":0, "max": 'unbounded'},
-                        {'name':"titles", "type":XMLString, "min":0, "max": 'unbounded'},
+                    {'name':"name", "type":XMLString, "min":0, "max": 1,"fullname":"name"},
+                    {'name':"birthdate", "type":XMLDateTime, "min":0, "max": 1, "fullname":"birthdate"},
+                    {'name':"age", "type":XMLInteger, "min":0, "max": 1,"fullname":"age"},
+                    {'name':"addresses", "type":Address, "min":0, "max": 'unbounded',"fullname":"addresses"},
+                    {'name':"titles", "type":XMLString, "min":0, "max": 'unbounded',"fullname":"titles"},
                         ], "__doc__": "a person info"})
 
 Employee = ComplexTypeMeta('Employee', (Person,), {
                 "_children":[
-                        {'name':"id", "type":XMLInteger, "min":1, "max": 1},
-                        {'name':"salary", "type":XMLDouble, "min":1, "max": 1},
+                    {'name':"id", "type":XMLInteger, "min":1, "max": 1,"fullname":"id"},
+                    {'name':"salary", "type":XMLDouble, "min":1, "max": 1,"fullname":"salary"},
                         ], "__doc__": "an employee info"})
 
 Level2 = ComplexTypeMeta('Level2', (), {
                 "_children":[
-                        {'name':"arg1", "type":XMLString, "min":1, "max": 1},
-                        {'name':"arg2", "type":XMLDouble, "min":1, "max": 1},
+                    {'name':"arg1", "type":XMLString, "min":1, "max": 1,"fullname":"arg1"},
+                    {'name':"arg2", "type":XMLDouble, "min":1, "max": 1,"fullname":"arg2"},
                         ], "__doc__": "don't know"})
 
 Level3 = ComplexTypeMeta('Level3', (), {
                 "_children":[
-                        {'name':"arg1", "type":XMLInteger, "min":1, "max": 1},
+                    {'name':"arg1", "type":XMLInteger, "min":1, "max": 1,"fullname":"arg1"},
                         ], "__doc__": "don't know"})
 Level4 = ComplexTypeMeta('Level4', (), {
                 "_children":[
-                        {'name':"arg1", "type":XMLString, "min":1, "max": 1},
+                    {'name':"arg1", "type":XMLString, "min":1, "max": 1,"fullname":"arg1"},
                         ], "__doc__": "don't know"})
 
 Level1 = ComplexTypeMeta('Level1', (), {
                 "_children":[
-                        {'name':"level2", "type":Level2, "min":1, "max": 1},
-                        {'name':"level3", "type":Level3, "min":0, "max": 'unbouneded'},
-                        {'name':"level4", "type":Level4, "min":0, "max": 'unbouneded'},
+                    {'name':"level2", "type":Level2, "min":1, "max": 1,"fullname":"level2"},
+                    {'name':"level3", "type":Level3, "min":0, "max": 'unbouneded', "fullname":"level3"},
+                    {'name':"level4", "type":Level4, "min":0, "max": 'unbouneded',"fullname":"level4"},
                         ], "__doc__": "don't know"})
 
 class TestClassSerializer(unittest.TestCase):