xmlclass/xmlclass.py
changeset 684 f10449b18dbe
parent 681 c141dad94ff4
child 698 314af37f7db2
--- a/xmlclass/xmlclass.py	Sat May 12 12:33:17 2012 +0200
+++ b/xmlclass/xmlclass.py	Fri May 18 18:49:49 2012 +0200
@@ -1238,15 +1238,16 @@
         classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
         classmembers["singleLineAttributes"] = True
         classmembers["compatibility"] = lambda x, y: None
+        classmembers["extraAttrs"] = {}
         
         class_definition = classobj(str(classname), bases, classmembers)
         setattr(class_definition, "__setattr__", generateSetattrMethod(self, class_definition, classinfos))
         class_infos = {"type": COMPILEDCOMPLEXTYPE,
-                "name": classname,
-                "check": generateClassCheckFunction(class_definition),
-                "initial": generateClassCreateFunction(class_definition),
-                "extract": generateClassExtractFunction(class_definition),
-                "generate": class_definition.generateXMLText}
+                       "name": classname,
+                       "check": generateClassCheckFunction(class_definition),
+                       "initial": generateClassCreateFunction(class_definition),
+                       "extract": generateClassExtractFunction(class_definition),
+                       "generate": class_definition.generateXMLText}
         
         if self.FileName is not None:
             self.ComputedClasses[self.FileName][classname] = class_definition
@@ -1410,6 +1411,7 @@
     elements = dict([(element["name"], element) for element in classinfos["elements"]])
     
     def loadXMLTreeMethod(self, tree, extras=[], derived=False):
+        self.extraAttrs = {}
         self.compatibility(tree)
         if not derived:
             children_structure = ""
@@ -1430,8 +1432,8 @@
             if attributes.has_key(attrname):
                 attributes[attrname]["attr_type"] = FindTypeInfos(factory, attributes[attrname]["attr_type"])
                 object.__setattr__(self, attrname, attributes[attrname]["attr_type"]["extract"](attr))
-            elif not classinfos.has_key("base") and attrname not in extras:
-                raise ValueError("Invalid attribute \"%s\" for \"%s\" element!" % (attrname, tree.nodeName))
+            elif not classinfos.has_key("base") and not attrname in extras and not self.extraAttrs.has_key(attrname):
+                self.extraAttrs[attrname] = GetAttributeValue(attr)
             required_attributes.pop(attrname, None)
         if len(required_attributes) > 0:
             raise ValueError("Required attributes %s missing for \"%s\" element!" % (", ".join(["\"%s\""%name for name in required_attributes]), tree.nodeName))
@@ -1489,8 +1491,10 @@
             text = u''
         
         first = True
+        
         if not classinfos.has_key("base"):
-            for attr, value in extras.items():
+            extras.update(self.extraAttrs)
+            for attr, value in extras.iteritems():
                 if not first and not self.singleLineAttributes:
                     text += u'\n%s' % (ind2)
                 text += u' %s=%s' % (attr, quoteattr(value))
@@ -1643,7 +1647,7 @@
                 elif element["elmt_type"]["type"] == SIMPLETYPE:
                     children.append({"name": element_name, "require": element["minOccurs"] != 0, 
                         "type": gettypeinfos(element["elmt_type"]["basename"], 
-                                              element["elmt_type"]["facets"]),
+                                             element["elmt_type"]["facets"]),
                         "value": getattr(self, element_name, None)})
                 else:
                     instance = getattr(self, element_name, None)
@@ -1677,6 +1681,9 @@
                         setattr(self, parts[0], elements[parts[0]]["elmt_type"]["extract"](value, False))
                 else:
                     instance = getattr(self, parts[0], None)
+                    if instance is None and elements[parts[0]]["minOccurs"] == 0:
+                        instance = elements[parts[0]]["elmt_type"]["initial"]()
+                        setattr(self, parts[0], instance)
                     if instance != None:
                         if len(parts) > 1:
                             instance.setElementValue(parts[1], value)
@@ -1702,6 +1709,7 @@
 """
 def generateInitMethod(factory, classinfos):
     def initMethod(self):
+        self.extraAttrs = {}
         if classinfos.has_key("base"):
             classinfos["base"].__init__(self)
         for attribute in classinfos["attributes"]: