xmlclass/xmlclass.py
changeset 1329 9d0cb01312f0
parent 1322 0a9227f743b3
child 1330 96b242e4c59d
--- a/xmlclass/xmlclass.py	Thu Sep 26 20:47:36 2013 +0900
+++ b/xmlclass/xmlclass.py	Fri Sep 27 09:32:39 2013 +0900
@@ -28,7 +28,9 @@
 from types import *
 from xml.dom import minidom
 from xml.sax.saxutils import escape, unescape, quoteattr
+from lxml import etree
 from new import classobj
+from collections import OrderedDict
 
 def CreateNode(name):
     node = minidom.Node()
@@ -533,28 +535,33 @@
     return GetModelNameList
 
 def GenerateAnyInfos(infos):
+    
+    def GetTextElement(tree):
+        if infos["namespace"][0] == "##any":
+            return tree.xpath("p")[0]
+        return tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0]
+    
     def ExtractAny(tree):
-        if tree.nodeName in ["#text", "#cdata-section"]:
-            return unicode(unescape(tree.data))
-        else:
-            return tree
-    
-    def GenerateAny(value, name=None, indent=0):
-        if isinstance(value, (StringType, UnicodeType)):
-            try:
-                value = value.decode("utf-8")
-            except:
-                pass
-            return u'<![CDATA[%s]]>\n' % value
-        else:
-            return value.toprettyxml(indent=" "*indent, encoding="utf-8")
+        return GetTextElement(tree).text
+    
+    def GenerateAny(tree, value):
+        GetTextElement(tree).text = etree.CDATA(value)
+        
+    def InitialAny():
+        if infos["namespace"][0] == "##any":
+            element_name = "p"
+        else:
+            element_name = "{%s}p" % infos["namespace"][0]
+        p = etree.Element(element_name)
+        p.text = etree.CDATA("")
+        return p
         
     return {
         "type": COMPLEXTYPE, 
         "extract": ExtractAny,
         "generate": GenerateAny,
-        "initial": lambda: "",
-        "check": lambda x: isinstance(x, (StringType, UnicodeType, minidom.Node))
+        "initial": InitialAny,
+        "check": lambda x: isinstance(x, (StringType, UnicodeType, etree.ElementBase))
     }
 
 def GenerateTagInfos(infos):
@@ -591,38 +598,23 @@
     
 def GetElementInitialValue(factory, infos):
     infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
-    if infos["minOccurs"] == 0 and infos["maxOccurs"] == 1:
-        if infos.has_key("default"):
-            return infos["elmt_type"]["extract"](infos["default"], False)
-        else:
-            return None
-    elif infos["minOccurs"] == 1 and infos["maxOccurs"] == 1:
-        return infos["elmt_type"]["initial"]()
+    if infos["minOccurs"] == 1:
+        element_name = factory.etreeNamespaceFormat % infos["name"]
+        if infos["elmt_type"]["type"] == SIMPLETYPE:
+            def initial_value():
+                value = etree.Element(element_name)
+                value.text = (infos["elmt_type"]["generate"](infos["elmt_type"]["initial"]()))
+                return value
+        else:
+            def initial_value():
+                value = infos["elmt_type"]["initial"]()
+                if infos["type"] != ANY:
+                    DefaultElementClass.__setattr__(value, "tag", element_name)
+                    value._init_()
+                return value
+        return [initial_value() for i in xrange(infos["minOccurs"])]
     else:
-        return [infos["elmt_type"]["initial"]() for i in xrange(infos["minOccurs"])]
-
-def HandleError(message, raise_exception):
-    if raise_exception:
-        raise ValueError(message)
-    return False
-
-def CheckElementValue(factory, name, infos, value, raise_exception=True):
-    infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
-    if value is None and raise_exception:
-        if not (infos["minOccurs"] == 0 and infos["maxOccurs"] == 1):
-            return HandleError("Attribute '%s' isn't optional." % name, raise_exception)
-    elif infos["maxOccurs"] == "unbounded" or infos["maxOccurs"] > 1:
-        if not isinstance(value, ListType):
-            return HandleError("Attribute '%s' must be a list." % name, raise_exception)
-        if len(value) < infos["minOccurs"] or infos["maxOccurs"] != "unbounded" and len(value) > infos["maxOccurs"]:
-            return HandleError("List out of bounds for attribute '%s'." % name, raise_exception)
-        if not reduce(lambda x, y: x and y, map(infos["elmt_type"]["check"], value), True):
-            return HandleError("Attribute '%s' must be a list of valid elements." % name, raise_exception)
-    elif infos.has_key("fixed") and value != infos["fixed"]:
-        return HandleError("Value of attribute '%s' can only be '%s'." % (name, str(infos["fixed"])), raise_exception)
-    else:
-        return infos["elmt_type"]["check"](value)
-    return True
+        return []
 
 def GetContentInfos(name, choices):
     for choice_infos in choices:
@@ -649,6 +641,7 @@
                         sequence_element["elmt_type"] = element_infos
         elif choice["elmt_type"] == "tag":
             choice["elmt_type"] = GenerateTagInfos(choice)
+            factory.AddToLookupClass(choice["name"], name, DefaultElementClass)
         else:
             choice_infos = factory.ExtractTypeInfos(choice["name"], name, choice["elmt_type"])
             if choice_infos is not None:
@@ -656,26 +649,6 @@
         choices.append((choice["name"], choice))
     return choices
 
-def ExtractContentElement(factory, tree, infos, content):
-    infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
-    if infos["maxOccurs"] == "unbounded" or infos["maxOccurs"] > 1:
-        if isinstance(content, ListType) and len(content) > 0 and \
-           content[-1]["name"] == tree.nodeName:
-            content_item = content.pop(-1)
-            content_item["value"].append(infos["elmt_type"]["extract"](tree))
-            return content_item
-        elif not isinstance(content, ListType) and \
-             content is not None and \
-             content["name"] == tree.nodeName:
-            return {"name": tree.nodeName, 
-                    "value": content["value"] + [infos["elmt_type"]["extract"](tree)]}
-        else:
-            return {"name": tree.nodeName, 
-                    "value": [infos["elmt_type"]["extract"](tree)]}
-    else:
-        return {"name": tree.nodeName, 
-                "value": infos["elmt_type"]["extract"](tree)}
-
 def GenerateContentInfos(factory, name, choices):
     choices_dict = {}
     for choice_name, infos in choices:
@@ -691,6 +664,9 @@
             if choices_dict.has_key(choice_name):
                 raise ValueError("'%s' element defined two times in choice" % choice_name)
             choices_dict[choice_name] = infos
+    prefix = ("%s:" % factory.TargetNamespace
+              if factory.TargetNamespace is not None else "")
+    choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys()))
     
     def GetContentInitial():
         content_name, infos = choices[0]
@@ -698,140 +674,15 @@
             content_value = []
             for i in xrange(infos["minOccurs"]):
                 for element_infos in infos["elements"]:
-                    value = GetElementInitialValue(factory, element_infos)
-                    if value is not None:
-                        if element_infos["type"] == CHOICE:
-                            content_value.append(value)
-                        else:
-                            content_value.append({"name": element_infos["name"], "value": value})
+                    content_value.extend(GetElementInitialValue(factory, element_infos))
         else:
             content_value = GetElementInitialValue(factory, infos)
-        return {"name": content_name, "value": content_value}
-        
-    def CheckContent(value):
-        if value["name"] != "sequence":
-            infos = choices_dict.get(value["name"], None)
-            if infos is not None:
-                return CheckElementValue(factory, value["name"], infos, value["value"], False)
-        elif len(value["value"]) > 0:
-            infos = choices_dict.get(value["value"][0]["name"], None)
-            if infos is None:
-                for choice_name, infos in choices:
-                    if infos["type"] == "sequence":
-                        for element_infos in infos["elements"]:
-                            if element_infos["type"] == CHOICE:
-                                infos = GetContentInfos(value["value"][0]["name"], element_infos["choices"])
-            if infos is not None:
-                sequence_number = 0
-                element_idx = 0
-                while element_idx < len(value["value"]):
-                    for element_infos in infos["elements"]:
-                        element_value = None
-                        if element_infos["type"] == CHOICE:
-                            choice_infos = None
-                            if element_idx < len(value["value"]):
-                                for choice in element_infos["choices"]:
-                                    if choice["name"] == value["value"][element_idx]["name"]:
-                                        choice_infos = choice
-                                        element_value = value["value"][element_idx]["value"]
-                                        element_idx += 1
-                                        break
-                            if ((choice_infos is not None and 
-                                 not CheckElementValue(factory, choice_infos["name"], choice_infos, element_value, False)) or
-                                (choice_infos is None and element_infos["minOccurs"] > 0)):
-                                raise ValueError("Invalid sequence value in attribute 'content'")
-                        else:
-                            if element_idx < len(value["value"]) and element_infos["name"] == value["value"][element_idx]["name"]:
-                                element_value = value["value"][element_idx]["value"]
-                                element_idx += 1
-                            if not CheckElementValue(factory, element_infos["name"], element_infos, element_value, False):
-                                raise ValueError("Invalid sequence value in attribute 'content'")
-                    sequence_number += 1
-                if sequence_number < infos["minOccurs"] or infos["maxOccurs"] != "unbounded" and sequence_number > infos["maxOccurs"]:
-                    raise ValueError("Invalid sequence value in attribute 'content'")
-                return True
-        else:
-            for element_name, infos in choices:
-                if element_name == "sequence":
-                    required = 0
-                    for element in infos["elements"]:
-                        if element["minOccurs"] > 0:
-                            required += 1
-                    if required == 0:
-                        return True
-        return False
-    
-    def ExtractContent(tree, content):
-        infos = choices_dict.get(tree.nodeName, None)
-        if infos is not None:
-            if infos["name"] == "sequence":
-                sequence_dict = dict([(element_infos["name"], element_infos) for element_infos in infos["elements"] if element_infos["type"] != CHOICE])
-                element_infos = sequence_dict.get(tree.nodeName)
-                if content is not None and \
-                   content["name"] == "sequence" and \
-                   len(content["value"]) > 0 and \
-                   choices_dict.get(content["value"][-1]["name"]) == infos:
-                    return {"name": "sequence",
-                            "value": content["value"] + [ExtractContentElement(factory, tree, element_infos, content["value"][-1])]}
-                else:
-                    return {"name": "sequence",
-                            "value": [ExtractContentElement(factory, tree, element_infos, None)]}
-            else:
-                return ExtractContentElement(factory, tree, infos, content)
-        else:
-            for choice_name, infos in choices:
-                if infos["type"] == "sequence":
-                    for element_infos in infos["elements"]:
-                        if element_infos["type"] == CHOICE:
-                            try:
-                                if content is not None and \
-                                    content["name"] == "sequence" and \
-                                    len(content["value"]) > 0:
-                                    return {"name": "sequence",
-                                            "value": content["value"] + [element_infos["elmt_type"]["extract"](tree, content["value"][-1])]}
-                                else:
-                                    return {"name": "sequence",
-                                            "value": [element_infos["elmt_type"]["extract"](tree, None)]}
-                            except:
-                                pass
-        raise ValueError("Invalid element \"%s\" for content!" % tree.nodeName)
-    
-    def GenerateContent(value, name=None, indent=0):
-        text = ""
-        if value["name"] != "sequence":
-            infos = choices_dict.get(value["name"], None)
-            if infos is not None:
-                infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
-                if infos["maxOccurs"] == "unbounded" or infos["maxOccurs"] > 1:
-                    for item in value["value"]:
-                        text += infos["elmt_type"]["generate"](item, value["name"], indent)
-                else:
-                    text += infos["elmt_type"]["generate"](value["value"], value["name"], indent)
-        elif len(value["value"]) > 0:
-            infos = choices_dict.get(value["value"][0]["name"], None)
-            if infos is None:
-                for choice_name, infos in choices:
-                    if infos["type"] == "sequence":
-                        for element_infos in infos["elements"]:
-                            if element_infos["type"] == CHOICE:
-                                infos = GetContentInfos(value["value"][0]["name"], element_infos["choices"])
-            if infos is not None:
-                sequence_dict = dict([(element_infos["name"], element_infos) for element_infos in infos["elements"]]) 
-                for element_value in value["value"]:
-                    element_infos = sequence_dict.get(element_value["name"])
-                    if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1:
-                        for item in element_value["value"]:
-                            text += element_infos["elmt_type"]["generate"](item, element_value["name"], indent)
-                    else:
-                        text += element_infos["elmt_type"]["generate"](element_value["value"], element_infos["name"], indent)
-        return text
+        return content_value
         
     return {
         "type": COMPLEXTYPE,
+        "choices_xpath": etree.XPath(choices_xpath, namespaces=factory.NSMAP),
         "initial": GetContentInitial,
-        "check": CheckContent,
-        "extract": ExtractContent,
-        "generate": GenerateContent
     }
 
 #-------------------------------------------------------------------------------
@@ -901,9 +752,11 @@
         self.XMLClassDefinitions = {}
         
         self.DefinedNamespaces = {}
+        self.NSMAP = {}
         self.Namespaces = {}
         self.SchemaNamespace = None
         self.TargetNamespace = None
+        self.etreeNamespaceFormat = "%s"
         
         self.CurrentCompilations = []
         
@@ -914,6 +767,8 @@
         else:
             self.ComputedClasses = {}
         self.ComputedClassesInfos = {}
+        self.ComputedClassesLookUp = {}
+        self.EquivalentClassesParent = {}
         self.AlreadyComputed = {}
 
     def GetQualifiedNameInfos(self, name, namespace=None, canbenone=False):
@@ -1016,7 +871,9 @@
                     attrs[name] = infos["extract"]["default"](attr)
             elif namespace == "xmlns":
                 infos = self.GetQualifiedNameInfos("anyURI", self.SchemaNamespace)
-                self.DefinedNamespaces[infos["extract"](attr)] = name
+                value = infos["extract"](attr)
+                self.DefinedNamespaces[value] = name
+                self.NSMAP[name] = value
             else:
                 raise ValueError("Invalid attribute \"%s\" for member \"%s\"!" % (qualified_name, node.nodeName))
         for attr in valid_attrs:
@@ -1063,20 +920,63 @@
 
     def ParseSchema(self):
         pass
-
+    
+    def AddEquivalentClass(self, name, base):
+        if name != base:
+            equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {})
+            equivalences[self.etreeNamespaceFormat % name] = True
+    
+    def AddDistinctionBetweenParentsInLookupClass(
+                                    self, lookup_classes, parent, typeinfos):
+        parent = (self.etreeNamespaceFormat % parent 
+                  if parent is not None else None)
+        parent_class = lookup_classes.get(parent)
+        if parent_class is not None:
+            if isinstance(parent_class, ListType):
+                if typeinfos not in parent_class:
+                    lookup_classes[parent].append(typeinfos)
+            elif parent_class != typeinfos:
+                lookup_classes[parent] = [parent_class, typeinfos]
+        else:
+            lookup_classes[parent] = typeinfos
+    
+    def AddToLookupClass(self, name, parent, typeinfos):
+        lookup_name = self.etreeNamespaceFormat % name
+        if isinstance(typeinfos, (StringType, UnicodeType)):
+            self.AddEquivalentClass(name, typeinfos)
+            typeinfos = self.etreeNamespaceFormat % typeinfos
+        lookup_classes = self.ComputedClassesLookUp.get(lookup_name)
+        if lookup_classes is None:
+            self.ComputedClassesLookUp[lookup_name] = (typeinfos, parent)
+        elif isinstance(lookup_classes, DictType):
+            self.AddDistinctionBetweenParentsInLookupClass(
+                lookup_classes, parent, typeinfos)
+        else:
+            lookup_classes = {
+                self.etreeNamespaceFormat % lookup_classes[1]
+                if lookup_classes[1] is not None else None: lookup_classes[0]}
+            self.AddDistinctionBetweenParentsInLookupClass(
+                lookup_classes, parent, typeinfos)
+            self.ComputedClassesLookUp[lookup_name] = lookup_classes
+    
     def ExtractTypeInfos(self, name, parent, typeinfos):
         if isinstance(typeinfos, (StringType, UnicodeType)):
-            namespace, name = DecomposeQualifiedName(typeinfos)
-            infos = self.GetQualifiedNameInfos(name, namespace)
+            namespace, type_name = DecomposeQualifiedName(typeinfos)
+            infos = self.GetQualifiedNameInfos(type_name, namespace)
+            if name != "base":
+                if infos["type"] == SIMPLETYPE:
+                    self.AddToLookupClass(name, parent, DefaultElementClass)
+                elif namespace == self.TargetNamespace:
+                    self.AddToLookupClass(name, parent, type_name)
             if infos["type"] == COMPLEXTYPE:
-                name, parent = self.SplitQualifiedName(name, namespace)
-                result = self.CreateClass(name, parent, infos)
+                type_name, parent = self.SplitQualifiedName(type_name, namespace)
+                result = self.CreateClass(type_name, parent, infos)
                 if result is not None and not isinstance(result, (UnicodeType, StringType)):
                     self.Namespaces[self.TargetNamespace][result["name"]] = result
                 return result
             elif infos["type"] == ELEMENT and infos["elmt_type"]["type"] == COMPLEXTYPE:
-                name, parent = self.SplitQualifiedName(name, namespace)
-                result = self.CreateClass(name, parent, infos["elmt_type"])
+                type_name, parent = self.SplitQualifiedName(type_name, namespace)
+                result = self.CreateClass(type_name, parent, infos["elmt_type"])
                 if result is not None and not isinstance(result, (UnicodeType, StringType)):
                     self.Namespaces[self.TargetNamespace][result["name"]] = result
                 return result
@@ -1086,7 +986,12 @@
             return self.CreateClass(name, parent, typeinfos)
         elif typeinfos["type"] == SIMPLETYPE:
             return typeinfos
-            
+    
+    def GetEquivalentParents(self, parent):
+        return reduce(lambda x, y: x + y,
+            [[p] + self.GetEquivalentParents(p)
+             for p in self.EquivalentClassesParent.get(parent, {}).keys()], [])
+    
     """
     Methods that generates the classes
     """
@@ -1123,6 +1028,21 @@
                             if result is not None and \
                                not isinstance(result, (UnicodeType, StringType)):
                                 self.Namespaces[self.TargetNamespace][result["name"]] = result
+        
+        for name, parents in self.ComputedClassesLookUp.iteritems():
+            if isinstance(parents, DictType):
+                computed_classes = parents.items()
+            elif parents[1] is not None:
+                computed_classes = [(self.etreeNamespaceFormat % parents[1], parents[0])]
+            else:
+                computed_classes = []
+            for parent, computed_class in computed_classes:
+                for equivalent_parent in self.GetEquivalentParents(parent):
+                    if not isinstance(parents, DictType):
+                        parents = dict(computed_classes)
+                        self.ComputedClassesLookUp[name] = parents
+                    parents[equivalent_parent] = computed_class
+        
         return self.ComputedClasses
 
     def CreateClass(self, name, parent, classinfos, baseclass = False):
@@ -1141,9 +1061,12 @@
         bases = []
         base_infos = classinfos.get("base", None)
         if base_infos is not None:
+            namespace, base_name = DecomposeQualifiedName(base_infos)
+            if namespace == self.TargetNamespace:
+                self.AddEquivalentClass(name, base_name)
             result = self.ExtractTypeInfos("base", name, base_infos)
             if result is None:
-                namespace, base_name = DecomposeQualifiedName(base_infos)                
+                namespace, base_name = DecomposeQualifiedName(base_infos)
                 if self.AlreadyComputed.get(base_name, False):
                     self.ComputeAfter.append((name, parent, classinfos))
                     if self.TargetNamespace is not None:
@@ -1164,7 +1087,7 @@
                 if classinfos["base"] is None:
                     raise ValueError("No class found for base type")
                 bases.append(classinfos["base"])
-        bases.append(object)
+        bases.append(DefaultElementClass)
         bases = tuple(bases)
         classmembers = {"__doc__": classinfos.get("doc", ""), "IsBaseClass": baseclass}
         
@@ -1177,11 +1100,8 @@
                     raise ValueError("\"%s\" type is not a simple type!" % attribute["attr_type"])
                 attrname = attribute["name"]
                 if attribute["use"] == "optional":
-                    classmembers[attrname] = None
                     classmembers["add%s"%attrname] = generateAddMethod(attrname, self, attribute)
                     classmembers["delete%s"%attrname] = generateDeleteMethod(attrname)
-                else:
-                    classmembers[attrname] = infos["initial"]()
                 classmembers["set%s"%attrname] = generateSetMethod(attrname)
                 classmembers["get%s"%attrname] = generateGetMethod(attrname)
             else:
@@ -1200,54 +1120,43 @@
                     classmembers["set%sbytype" % elmtname] = generateSetChoiceByTypeMethod(self, element["choices"])
                 infos = GenerateContentInfos(self, name, choices)
             elif element["type"] == ANY:
-                elmtname = element["name"] = "text"
+                elmtname = element["name"] = "anyText"
                 element["minOccurs"] = element["maxOccurs"] = 1
                 infos = GenerateAnyInfos(element)
             else:
                 elmtname = element["name"]
                 if element["elmt_type"] == "tag":
                     infos = GenerateTagInfos(element)
+                    self.AddToLookupClass(element["name"], name, DefaultElementClass)
                 else:
                     infos = self.ExtractTypeInfos(element["name"], name, element["elmt_type"])
             if infos is not None:
                 element["elmt_type"] = infos
             if element["maxOccurs"] == "unbounded" or element["maxOccurs"] > 1:
-                classmembers[elmtname] = []
                 classmembers["append%s" % elmtname] = generateAppendMethod(elmtname, element["maxOccurs"], self, element)
                 classmembers["insert%s" % elmtname] = generateInsertMethod(elmtname, element["maxOccurs"], self, element)
                 classmembers["remove%s" % elmtname] = generateRemoveMethod(elmtname, element["minOccurs"])
                 classmembers["count%s" % elmtname] = generateCountMethod(elmtname)
             else:
                 if element["minOccurs"] == 0:
-                    classmembers[elmtname] = None
                     classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element)
                     classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname)
-                elif not isinstance(element["elmt_type"], (UnicodeType, StringType)):
-                    classmembers[elmtname] = element["elmt_type"]["initial"]()
-                else:
-                    classmembers[elmtname] = None
             classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
             classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
             
-        classmembers["__init__"] = generateInitMethod(self, classinfos)
-        classmembers["getStructure"] = generateStructureMethod(classinfos)
-        classmembers["loadXMLTree"] = generateLoadXMLTree(self, classinfos)
-        classmembers["generateXMLText"] = generateGenerateXMLText(self, classinfos)
+        classmembers["_init_"] = generateInitMethod(self, classinfos)
+        classmembers["StructurePattern"] = GetStructurePattern(classinfos)
         classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
         classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
         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, "__getattr__", generateGetattrMethod(self, class_definition, classinfos))
         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}
+        }
         
         if self.FileName is not None:
             self.ComputedClasses[self.FileName][classname] = class_definition
@@ -1255,6 +1164,9 @@
             self.ComputedClasses[classname] = class_definition
         self.ComputedClassesInfos[classname] = class_infos
         
+        self.AddToLookupClass(name, parent, class_definition)
+        self.AddToLookupClass(classname, None, class_definition)
+            
         return class_infos
 
     """
@@ -1281,69 +1193,6 @@
             print classname
 
 """
-Method that generate the method for checking a class instance
-"""
-def generateClassCheckFunction(class_definition):
-    def classCheckfunction(instance):
-        return isinstance(instance, class_definition)
-    return classCheckfunction
-
-"""
-Method that generate the method for creating a class instance
-"""
-def generateClassCreateFunction(class_definition):
-    def classCreatefunction():
-        return class_definition()
-    return classCreatefunction
-
-"""
-Method that generate the method for extracting a class instance
-"""
-def generateClassExtractFunction(class_definition):
-    def classExtractfunction(node):
-        instance = class_definition()
-        instance.loadXMLTree(node)
-        return instance
-    return classExtractfunction
-
-"""
-Method that generate the method for loading an xml tree by following the
-attributes list defined
-"""
-def generateSetattrMethod(factory, class_definition, classinfos):
-    attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
-    optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"])
-    elements = dict([(element["name"], element) for element in classinfos["elements"]])
-    
-    def setattrMethod(self, name, value):
-        if attributes.has_key(name):
-            attributes[name]["attr_type"] = FindTypeInfos(factory, attributes[name]["attr_type"])
-            if value is None:
-                if optional_attributes.get(name, False):
-                    return object.__setattr__(self, name, None)
-                else:
-                    raise ValueError("Attribute '%s' isn't optional." % name)
-            elif attributes[name].has_key("fixed") and value != attributes[name]["fixed"]:
-                raise ValueError, "Value of attribute '%s' can only be '%s'."%(name, str(attributes[name]["fixed"]))
-            elif attributes[name]["attr_type"]["check"](value):
-                return object.__setattr__(self, name, value)
-            else:
-                raise ValueError("Invalid value for attribute '%s'." % (name))
-        elif elements.has_key(name):
-            if CheckElementValue(factory, name, elements[name], value):
-                return object.__setattr__(self, name, value)
-            else:
-                raise ValueError("Invalid value for attribute '%s'." % (name))
-        elif classinfos.has_key("base"):
-            return classinfos["base"].__setattr__(self, name, value)
-        elif class_definition.__dict__.has_key(name):
-            return object.__setattr__(self, name, value)
-        else:
-            raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name))
-        
-    return setattrMethod
-
-"""
 Method that generate the method for generating the xml tree structure model by 
 following the attributes list defined
 """
@@ -1369,7 +1218,10 @@
             return "(?:%s){%d,%d}" % (name, infos["minOccurs"], 
                                        infos["maxOccurs"])
 
-def GetStructure(classinfos):
+def GetStructurePattern(classinfos):
+    base_structure_pattern = (
+        classinfos["base"].StructurePattern.pattern[:-1]
+        if classinfos.has_key("base") else "")
     elements = []
     for element in classinfos["elements"]:
         if element["type"] == ANY:
@@ -1380,7 +1232,7 @@
             choices = []
             for infos in element["choices"]:
                 if infos["type"] == "sequence":
-                    structure = "(?:%s)" % GetStructure(infos)
+                    structure = "(?:%s)" % GetStructurePattern(infos)
                 else:
                     structure = "%s " % infos["name"]
                 choices.append(ComputeMultiplicity(structure, infos))
@@ -1390,170 +1242,139 @@
         else:
             elements.append(ComputeMultiplicity("%s " % element["name"], element))
     if classinfos.get("order", True) or len(elements) == 0:
-        return "".join(elements)
+        return re.compile(base_structure_pattern + "".join(elements) + "$")
     else:
         raise ValueError("XSD structure not yet supported!")
 
-def generateStructureMethod(classinfos):
-    def getStructureMethod(self):
-        structure = GetStructure(classinfos)
-        if classinfos.has_key("base"):
-            return classinfos["base"].getStructure(self) + structure
-        return structure
-    return getStructureMethod
-
 """
-Method that generate the method for loading an xml tree by following the
-attributes list defined
+Method that generate the method for creating a class instance
 """
-def generateLoadXMLTree(factory, classinfos):
+def generateClassCreateFunction(class_definition):
+    def classCreatefunction():
+        return class_definition()
+    return classCreatefunction
+
+def generateGetattrMethod(factory, class_definition, classinfos):
     attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
+    optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"])
     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 = ""
-            for node in tree.childNodes:
-                if not (node.nodeName == "#text" and node.data.strip() == "") and node.nodeName != "#comment":
-                    children_structure += "%s " % node.nodeName
-            structure_pattern = self.getStructure()
-            if structure_pattern != "":
-                structure_model = re.compile("(%s)$" % structure_pattern)
-                result = structure_model.match(children_structure)
-                if not result:
-                    raise ValueError("Invalid structure for \"%s\" children!." % tree.nodeName)
-        required_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "required"])
-        if classinfos.has_key("base"):
-            extras.extend([attr["name"] for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
-            classinfos["base"].loadXMLTree(self, tree, extras, True)
-        for attrname, attr in tree._attrs.iteritems():
-            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 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))
-        first = {}
-        for node in tree.childNodes:
-            name = node.nodeName
-            if name == "#text" and node.data.strip() == "" or name == "#comment":
-                continue
-            elif elements.has_key(name):
-                elements[name]["elmt_type"] = FindTypeInfos(factory, elements[name]["elmt_type"])
-                if elements[name]["maxOccurs"] == "unbounded" or elements[name]["maxOccurs"] > 1:
-                    if first.get(name, True):
-                        object.__setattr__(self, name, [elements[name]["elmt_type"]["extract"](node)])
-                        first[name] = False
+    def getattrMethod(self, name):
+        if attributes.has_key(name):
+            attribute_infos = attributes[name]
+            attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"])
+            value = self.get(name)
+            if value is not None:
+                return attribute_infos["attr_type"]["extract"](value, extract=False)
+            elif attribute_infos.has_key("fixed"):
+                return attribute_infos["attr_type"]["extract"](attribute_infos["fixed"], extract=False)
+            elif attribute_infos.has_key("default"):
+                return attribute_infos["attr_type"]["extract"](attribute_infos["default"], extract=False)
+            return None
+        
+        elif elements.has_key(name):
+            element_infos = elements[name]
+            element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
+            if element_infos["type"] == CHOICE:
+                content = element_infos["elmt_type"]["choices_xpath"](self)
+                if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1:
+                    return content
+                elif len(content) > 0:
+                    return content[0]
+                return None 
+            elif element_infos["type"] == ANY:
+                return element_infos["elmt_type"]["extract"](self)
+            elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE:
+                return element_infos["elmt_type"]["extract"](self.text, extract=False)
+            else:
+                element_name = factory.etreeNamespaceFormat % name
+                if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1:
+                    values = self.findall(element_name)
+                    if element_infos["elmt_type"]["type"] == SIMPLETYPE:
+                        return map(lambda value:
+                            element_infos["elmt_type"]["extract"](value.text, extract=False), 
+                            values)
+                    return values
+                else:
+                    value = self.find(element_name)
+                    if element_infos["elmt_type"]["type"] == SIMPLETYPE:
+                        return element_infos["elmt_type"]["extract"](value.text, extract=False)
+                    return value
+            
+        elif classinfos.has_key("base"):
+            return classinfos["base"].__getattr__(self, name)
+        
+        return DefaultElementClass.__getattribute__(self, name)
+    
+    return getattrMethod
+
+def generateSetattrMethod(factory, class_definition, classinfos):
+    attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
+    optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"])
+    elements = OrderedDict([(element["name"], element) for element in classinfos["elements"]])
+    
+    def setattrMethod(self, name, value):
+        if attributes.has_key(name):
+            attribute_infos = attributes[name]
+            attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"])
+            if optional_attributes.get(name, False):
+                default = attribute_infos.get("default", None)
+                if value is None or value == default:
+                    self.attrib.pop(name, None)
+                    return
+            elif attribute_infos.has_key("fixed"):
+                return
+            return self.set(name, attribute_infos["attr_type"]["generate"](value))
+        
+        elif elements.has_key(name):
+            element_infos = elements[name]
+            element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
+            if element_infos["type"] == ANY:
+                element_infos["elmt_type"]["generate"](self, value)
+            
+            elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE:
+                self.text = element_infos["elmt_type"]["generate"](value)
+            
+            else:
+                prefix = ("%s:" % factory.TargetNamespace
+                          if factory.TargetNamespace is not None else "")
+                element_xpath = (prefix + name
+                                 if name != "content"
+                                 else elements["content"]["elmt_type"]["choices_xpath"].path)
+                
+                for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
+                    self.remove(element)
+                
+                if value is not None:
+                    element_idx = elements.keys().index(name)
+                    if element_idx > 0:
+                        previous_elements_xpath = "|".join(map(
+                            lambda x: prefix + x
+                                      if x != "content"
+                                      else elements["content"]["elmt_type"]["choices_xpath"].path,
+                            elements.keys()[:element_idx]))
+                        
+                        insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
                     else:
-                        getattr(self, name).append(elements[name]["elmt_type"]["extract"](node))
-                else:
-                    object.__setattr__(self, name, elements[name]["elmt_type"]["extract"](node))
-            elif elements.has_key("text"):
-                if elements["text"]["maxOccurs"] == "unbounded" or elements["text"]["maxOccurs"] > 1:
-                    if first.get("text", True):
-                        object.__setattr__(self, "text", [elements["text"]["elmt_type"]["extract"](node)])
-                        first["text"] = False
-                    else:
-                        getattr(self, "text").append(elements["text"]["elmt_type"]["extract"](node))
-                else:
-                    object.__setattr__(self, "text", elements["text"]["elmt_type"]["extract"](node))
-            elif elements.has_key("content"):
-                if name in ["#cdata-section", "#text"]:
-                    if elements["content"]["elmt_type"]["type"] == SIMPLETYPE:
-                        object.__setattr__(self, "content", elements["content"]["elmt_type"]["extract"](node.data, False))
-                else:
-                    content = getattr(self, "content")
-                    if elements["content"]["maxOccurs"] == "unbounded" or elements["content"]["maxOccurs"] > 1:
-                        if first.get("content", True):
-                            object.__setattr__(self, "content", [elements["content"]["elmt_type"]["extract"](node, None)])
-                            first["content"] = False
-                        else:
-                            content.append(elements["content"]["elmt_type"]["extract"](node, content))
-                    else:
-                        object.__setattr__(self, "content", elements["content"]["elmt_type"]["extract"](node, content))
-    return loadXMLTreeMethod
-        
-
-"""
-Method that generates the method for generating an xml text by following the
-attributes list defined
-"""
-def generateGenerateXMLText(factory, classinfos):
-    def generateXMLTextMethod(self, name, indent=0, extras={}, derived=False):
-        ind1, ind2 = getIndent(indent, name)
-        if not derived:
-            text = ind1 + u'<%s' % name
-        else:
-            text = u''
-        
-        first = True
-        
-        if not classinfos.has_key("base"):
-            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))
-                first = False
-            extras.clear()
-        for attr in classinfos["attributes"]:
-            if attr["use"] != "prohibited":
-                attr["attr_type"] = FindTypeInfos(factory, attr["attr_type"])
-                value = getattr(self, attr["name"], None)
-                if value != None:
-                    computed_value = attr["attr_type"]["generate"](value)
-                else:
-                    computed_value = None
-                if attr["use"] != "optional" or (value != None and \
-                   computed_value != attr.get("default", attr["attr_type"]["generate"](attr["attr_type"]["initial"]()))):
-                    if classinfos.has_key("base"):
-                        extras[attr["name"]] = computed_value
-                    else:
-                        if not first and not self.singleLineAttributes:
-                            text += u'\n%s' % (ind2)
-                        text += ' %s=%s' % (attr["name"], quoteattr(computed_value))
-                    first = False
-        if classinfos.has_key("base"):
-            first, new_text = classinfos["base"].generateXMLText(self, name, indent, extras, True)
-            text += new_text
-        else:
-            first = True
-        for element in classinfos["elements"]:
-            element["elmt_type"] = FindTypeInfos(factory, element["elmt_type"])
-            value = getattr(self, element["name"], None)
-            if element["minOccurs"] == 0 and element["maxOccurs"] == 1:
-                if value is not None:
-                    if first:
-                        text += u'>\n'
-                        first = False
-                    text += element["elmt_type"]["generate"](value, element["name"], indent + 1)
-            elif element["minOccurs"] == 1 and element["maxOccurs"] == 1:
-                if first:
-                    text += u'>\n'
-                    first = False
-                if element["name"] == "content" and element["elmt_type"]["type"] == SIMPLETYPE:
-                    text += element["elmt_type"]["generate"](value)
-                else:
-                    text += element["elmt_type"]["generate"](value, element["name"], indent + 1)
-            else:
-                if first and len(value) > 0:
-                    text += u'>\n'
-                    first = False
-                for item in value:
-                    text += element["elmt_type"]["generate"](item, element["name"], indent + 1)
-        if not derived:
-            if first:
-                text += u'/>\n'
-            else:
-                text += ind1 + u'</%s>\n' % (name)
-            return text
-        else:
-            return first, text
-    return generateXMLTextMethod
+                        insertion_point = 0
+                    
+                    if not isinstance(value, ListType):
+                        value = [value]
+                    
+                    for element in reversed(value):
+                        if element_infos["elmt_type"]["type"] == SIMPLETYPE:
+                            tmp_element = etree.Element(factory.etreeNamespaceFormat % name)
+                            tmp_element.text = element_infos["elmt_type"]["generate"](element)
+                            element = tmp_element
+                        self.insert(insertion_point, element)
+        
+        elif classinfos.has_key("base"):
+            return classinfos["base"].__setattr__(self, name, value)
+        
+        else:
+            raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name))
+        
+    return setattrMethod
 
 def gettypeinfos(name, facets):
     if facets.has_key("enumeration") and facets["enumeration"][0] is not None:
@@ -1611,7 +1432,7 @@
                                              elements[parts[0]]["elmt_type"]["facets"])
                     value = getattr(self, parts[0], "")
                 elif parts[0] == "content":
-                    return self.content["value"].getElementInfos(self.content["name"], path)
+                    return self.content.getElementInfos(self.content.getLocalTag(), path)
                 else:
                     attr = getattr(self, parts[0], None)
                     if attr is None:
@@ -1622,7 +1443,7 @@
                         return attr.getElementInfos(parts[0], parts[1])
             elif elements.has_key("content"):
                 if len(parts) > 0:
-                    return self.content["value"].getElementInfos(name, path)
+                    return self.content.getElementInfos(name, path)
             elif classinfos.has_key("base"):
                 classinfos["base"].getElementInfos(name, path)
             else:
@@ -1640,15 +1461,9 @@
                     if self.content is None:
                         value = ""
                     else:
-                        value = self.content["name"]
-                        if self.content["value"] is not None:
-                            if self.content["name"] == "sequence":
-                                choices_dict = dict([(choice["name"], choice) for choice in element["choices"]])
-                                sequence_infos = choices_dict.get("sequence", None)
-                                if sequence_infos is not None:
-                                    children.extend([item.getElementInfos(infos["name"]) for item, infos in zip(self.content["value"], sequence_infos["elements"])])
-                            else:
-                                children.extend(self.content["value"].getElementInfos(self.content["name"])["children"])
+                        value = self.content.getLocalTag()
+                        if self.content is not None:
+                            children.extend(self.content.getElementInfos(value)["children"])
                 elif element["elmt_type"]["type"] == SIMPLETYPE:
                     children.append({"name": element_name, "require": element["minOccurs"] != 0, 
                         "type": gettypeinfos(element["elmt_type"]["basename"], 
@@ -1705,13 +1520,13 @@
                             instance.setElementValue(None, value)
             elif elements.has_key("content"):
                 if len(parts) > 0:
-                    self.content["value"].setElementValue(path, value)
+                    self.content.setElementValue(path, value)
             elif classinfos.has_key("base"):
                 classinfos["base"].setElementValue(self, path, value)
         elif elements.has_key("content"):
             if value == "":
                 if elements["content"]["minOccurs"] == 0:
-                    self.setcontent(None)
+                    self.setcontent([])
                 else:
                     raise ValueError("\"content\" element is required!")
             else:
@@ -1723,20 +1538,21 @@
 """
 def generateInitMethod(factory, classinfos):
     def initMethod(self):
-        self.extraAttrs = {}
         if classinfos.has_key("base"):
-            classinfos["base"].__init__(self)
+            classinfos["base"]._init_(self)
         for attribute in classinfos["attributes"]:
             attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"])
             if attribute["use"] == "required":
-                setattr(self, attribute["name"], attribute["attr_type"]["initial"]())
-            elif attribute["use"] == "optional":
-                if attribute.has_key("default"):
-                    setattr(self, attribute["name"], attribute["attr_type"]["extract"](attribute["default"], False))
-                else:
-                    setattr(self, attribute["name"], None)
+                self.set(attribute["name"], attribute["attr_type"]["generate"](attribute["attr_type"]["initial"]()))
         for element in classinfos["elements"]:
-            setattr(self, element["name"], GetElementInitialValue(factory, element))
+            if element["type"] != CHOICE:
+                element_name = (
+                    etree.QName(factory.NSMAP["xhtml"], "p")
+                    if element["type"] == ANY
+                    else factory.etreeNamespaceFormat % element["name"])
+                initial = GetElementInitialValue(factory, element)
+                if initial is not None:
+                    map(self.append, initial)
     return initMethod
 
 def generateSetMethod(attr):
@@ -1753,18 +1569,16 @@
     def addMethod(self):
         if infos["type"] == ATTRIBUTE:
             infos["attr_type"] = FindTypeInfos(factory, infos["attr_type"])
-            initial = infos["attr_type"]["initial"]
-            extract = infos["attr_type"]["extract"]
+            if not infos.has_key("default"):
+                setattr(self, attr, infos["attr_type"]["initial"]())
         elif infos["type"] == ELEMENT:
             infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
-            initial = infos["elmt_type"]["initial"]
-            extract = infos["elmt_type"]["extract"]
+            value = infos["elmt_type"]["initial"]()
+            DefaultElementClass.__setattr__(value, "tag", factory.etreeNamespaceFormat % attr)
+            setattr(self, attr, value)
+            value._init_()
         else:
             raise ValueError("Invalid class attribute!")
-        if infos.has_key("default"):
-            setattr(self, attr, extract(infos["default"], False))
-        else:
-            setattr(self, attr, initial())
     return addMethod
 
 def generateDeleteMethod(attr):
@@ -1777,10 +1591,10 @@
         infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
         attr_list = getattr(self, attr)
         if maxOccurs == "unbounded" or len(attr_list) < maxOccurs:
-            if infos["elmt_type"]["check"](value):
-                attr_list.append(value)
+            if len(attr_list) == 0:
+                setattr(self, attr, [value])
             else:
-                raise ValueError("\"%s\" value isn't valid!" % attr)
+                attr_list[-1].addnext(value)
         else:
             raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr))
     return appendMethod
@@ -1790,10 +1604,12 @@
         infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
         attr_list = getattr(self, attr)
         if maxOccurs == "unbounded" or len(attr_list) < maxOccurs:
-            if infos["elmt_type"]["check"](value):
-                attr_list.insert(index, value)
+            if len(attr_list) == 0:
+                setattr(self, attr, [value])
+            elif index == 0:
+                attr_list[0].addprevious(value)
             else:
-                raise ValueError("\"%s\" value isn't valid!" % attr)
+                attr_list[min(index - 1, len(attr_list) - 1)].addnext(value)
         else:
             raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr))
     return insertMethod
@@ -1805,24 +1621,26 @@
 
 def generateSetChoiceByTypeMethod(factory, choice_types):
     choices = dict([(choice["name"], choice) for choice in choice_types])
-    def setChoiceMethod(self, type):
-        if not choices.has_key(type):
-            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type)
-        choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"])
-        new_element = choices[type]["elmt_type"]["initial"]()
-        self.content = {"name": type, "value": new_element}
-        return new_element
+    def setChoiceMethod(self, content_type):
+        if not choices.has_key(content_type):
+            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
+        choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
+        new_content = choices[content_type]["elmt_type"]["initial"]()
+        DefaultElementClass.__setattr__(new_content, "tag", factory.etreeNamespaceFormat % content_type)
+        self.content = new_content
+        return new_content
     return setChoiceMethod
 
 def generateAppendChoiceByTypeMethod(maxOccurs, factory, choice_types):
     choices = dict([(choice["name"], choice) for choice in choice_types])
-    def appendChoiceMethod(self, type):
-        if not choices.has_key(type):
-            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type)
-        choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"])
+    def appendChoiceMethod(self, content_type):
+        if not choices.has_key(content_type):
+            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
+        choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
-            new_element = choices[type]["elmt_type"]["initial"]()
-            self.content.append({"name": type, "value": new_element})
+            new_element = choices[content_type]["elmt_type"]["initial"]()
+            DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type)
+            self.appendcontent(new_element)
             return new_element
         else:
             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
@@ -1830,13 +1648,14 @@
 
 def generateInsertChoiceByTypeMethod(maxOccurs, factory, choice_types):
     choices = dict([(choice["name"], choice) for choice in choice_types])
-    def insertChoiceMethod(self, index, type):
-        if not choices.has_key(type):
-            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type)
-        choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"])
+    def insertChoiceMethod(self, index, content_type):
+        if not choices.has_key(content_type):
+            raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
+        choices[type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
-            new_element = choices[type]["elmt_type"]["initial"]()
-            self.content.insert(index, {"name" : type, "value" : new_element})
+            new_element = choices[content_type]["elmt_type"]["initial"]()
+            DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type)
+            self.insertcontent(index, new_element)
             return new_element
         else:
             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
@@ -1846,7 +1665,7 @@
     def removeMethod(self, index):
         attr_list = getattr(self, attr)
         if len(attr_list) > minOccurs:
-            getattr(self, attr).pop(index)
+            self.remove(attr_list[index])
         else:
             raise ValueError("There can't be less than %d values in \"%s\"!" % (minOccurs, attr))
     return removeMethod
@@ -1857,16 +1676,127 @@
     return countMethod
 
 """
-This function generate the classes from a class factory
+This function generate a xml parser from a class factory
 """
-def GenerateClasses(factory):
+
+NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ")
+
+class DefaultElementClass(etree.ElementBase):
+    
+    StructurePattern = re.compile("$")
+    
+    def _init_(self):
+        pass
+    
+    def getLocalTag(self):
+        return etree.QName(self.tag).localname
+        
+    def tostring(self):
+        return NAMESPACE_PATTERN.sub("", etree.tostring(self, pretty_print=True))
+
+class XMLElementClassLookUp(etree.PythonElementClassLookup):
+    
+    def __init__(self, classes, *args, **kwargs):
+        etree.PythonElementClassLookup.__init__(self, *args, **kwargs)
+        self.LookUpClasses = classes
+    
+    def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass):
+        element_class = self.LookUpClasses.get(element_tag, (default, None))
+        if not isinstance(element_class, DictType):
+            if isinstance(element_class[0], (StringType, UnicodeType)):
+                return self.GetElementClass(element_class[0], default=default)
+            return element_class[0]
+        
+        element_with_parent_class = element_class.get(parent_tag, default)
+        if isinstance(element_with_parent_class, (StringType, UnicodeType)):
+            return self.GetElementClass(element_with_parent_class, default=default)
+        return element_with_parent_class
+        
+    def lookup(self, document, element):
+        parent = element.getparent()
+        element_class = self.GetElementClass(element.tag, 
+            parent.tag if parent is not None else None)
+        if isinstance(element_class, ListType):
+            children = "".join([
+                "%s " % etree.QName(child.tag).localname
+                for child in element])
+            for possible_class in element_class:
+                if isinstance(possible_class, (StringType, UnicodeType)):
+                    possible_class = self.GetElementClass(possible_class)
+                if possible_class.StructurePattern.match(children) is not None:
+                    return possible_class
+            return element_class[0]
+        return element_class
+
+class XMLClassParser(etree.XMLParser):
+
+    def __init__(self, namespaces, default_namespace_format, base_class, *args, **kwargs):
+        etree.XMLParser.__init__(self, *args, **kwargs)
+        self.DefaultNamespaceFormat = default_namespace_format
+        self.NSMAP = namespaces
+        targetNamespace = etree.QName(default_namespace_format % "d").namespace
+        if targetNamespace is not None:
+            self.RootNSMAP = {
+                name if targetNamespace != uri else None: uri
+                for name, uri in namespaces.iteritems()}
+        else:
+            self.RootNSMAP = namespaces
+        self.BaseClass = base_class
+    
+    def set_element_class_lookup(self, class_lookup):
+        etree.XMLParser.set_element_class_lookup(self, class_lookup)
+        self.ClassLookup = class_lookup
+    
+    def Dumps(self, xml_obj):
+        return etree.tostring(xml_obj)
+    
+    def Loads(self, xml_string):
+        return etree.fromstring(xml_string, self)
+    
+    def CreateRoot(self):
+        if self.BaseClass is not None:
+            root = self.makeelement(
+                self.DefaultNamespaceFormat % self.BaseClass[0],
+                nsmap=self.RootNSMAP)
+            root._init_()
+            return root
+        return None
+    
+    def GetElementClass(self, element_tag, parent_tag=None):
+        return self.ClassLookup.GetElementClass(
+            self.DefaultNamespaceFormat % element_tag, 
+            self.DefaultNamespaceFormat % parent_tag 
+            if parent_tag is not None else parent_tag, 
+            None)
+    
+    def CreateElement(self, element_tag, parent_tag=None, class_idx=None):
+        element_class = self.GetElementClass(element_tag, parent_tag)
+        if isinstance(element_class, ListType):
+            if class_idx is not None and class_idx < len(element_class):
+                new_element = element_class[class_idx]()
+            else:
+                raise ValueError, "No corresponding class found!"
+        else:
+            new_element = element_class()
+        DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
+        new_element._init_()
+        return new_element
+    
+def GenerateParser(factory, xsdstring):
     ComputedClasses = factory.CreateClasses()
-    if factory.FileName is not None and len(ComputedClasses) == 1:
-        UpdateXMLClassGlobals(ComputedClasses[factory.FileName])
-        return ComputedClasses[factory.FileName]
-    else:
-        UpdateXMLClassGlobals(ComputedClasses)
-        return ComputedClasses
-
-def UpdateXMLClassGlobals(classes):
-    globals().update(classes)
+    
+    if factory.FileName is not None:
+        ComputedClasses = ComputedClasses[factory.FileName]
+    BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
+       
+    parser = XMLClassParser(
+        factory.NSMAP,
+        factory.etreeNamespaceFormat,
+        BaseClass[0] if len(BaseClass) == 1 else None,
+        schema = etree.XMLSchema(etree.fromstring(xsdstring)),
+        strip_cdata = False, remove_blank_text=True)
+    class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp)
+    parser.set_element_class_lookup(class_lookup)
+    
+    return parser
+