Second stage of xmlclass refactoring using lxml , project are loaded and displayed successfully
authorLaurent Bessard
Wed, 28 Aug 2013 11:52:46 +0200
changeset 1291 42ea51d083ce
parent 1290 13ee5f4ab612
child 1292 bac1b86276d9
Second stage of xmlclass refactoring using lxml , project are loaded and displayed successfully
PLCControler.py
plcopen/plcopen.py
xmlclass/xmlclass.py
--- a/PLCControler.py	Mon Aug 26 10:55:03 2013 +0200
+++ b/PLCControler.py	Wed Aug 28 11:52:46 2013 +0200
@@ -66,16 +66,14 @@
                   ITEM_VAR_INOUT
                  ] = range(17, 24)
 
-VAR_CLASS_INFOS = dict(
-    [(name, (PLCOpenParser.GetElementClass(classname, "interface"), symbol))
-     for name, classname, symbol in 
-     [("Local",    "localVars",    ITEM_VAR_LOCAL),
-      ("Global",   "globalVars",   ITEM_VAR_GLOBAL),
-      ("External", "externalVars", ITEM_VAR_EXTERNAL),
-      ("Temp",     "tempVars",     ITEM_VAR_TEMP),
-      ("Input",    "inputVars",    ITEM_VAR_INPUT),
-      ("Output",   "outputVars",   ITEM_VAR_OUTPUT),
-      ("InOut",    "inOutVars",    ITEM_VAR_INOUT)]])
+VAR_CLASS_INFOS = {
+    "Local":    ("localVars",    ITEM_VAR_LOCAL),
+    "Global":   ("globalVars",   ITEM_VAR_GLOBAL),
+    "External": ("externalVars", ITEM_VAR_EXTERNAL),
+    "Temp":     ("tempVars",     ITEM_VAR_TEMP),
+    "Input":    ("inputVars",    ITEM_VAR_INPUT),
+    "Output":   ("outputVars",   ITEM_VAR_OUTPUT),
+    "InOut":    ("inOutVars",    ITEM_VAR_INOUT)}
 
 POU_TYPES = {"program": ITEM_PROGRAM,
              "functionBlock": ITEM_FUNCTIONBLOCK,
@@ -241,11 +239,15 @@
         self.Project.setfileHeader(properties)
         self.Project.setcontentHeader(properties)
         self.SetFilePath("")
+        
+        ## To remove when project buffering ready
+        self.ProjectBufferEnabled = False
+        
         # Initialize the project buffer
         self.CreateProjectBuffer(False)
         self.ProgramChunks = []
         self.ProgramOffset = 0
-        self.NextCompiledProject = self.Copy(self.Project)
+        self.NextCompiledProject = self.Project #self.Copy(self.Project)
         self.CurrentCompiledProject = None
         self.Buffering = False
     
@@ -392,8 +394,9 @@
 
     def GetPouVariableInfos(self, project, variable, var_class, debug=False):
         vartype_content = variable.gettype().getcontent()
-        if vartype_content["name"] == "derived":
-            var_type = vartype_content["value"].getname()
+        vartype_content_type = vartype_content.getLocalTag()
+        if vartype_content_type == "derived":
+            var_type = vartype_content.getname()
             pou_type = None
             pou = project.getpou(var_type)
             if pou is not None:
@@ -421,15 +424,15 @@
                         "class": var_class,
                         "edit": False,
                         "debug": False}
-        elif vartype_content["name"] in ["string", "wstring"]:
+        elif vartype_content_type in ["string", "wstring"]:
             return {"name": variable.getname(), 
-                    "type": vartype_content["name"].upper(), 
+                    "type": vartype_content_type.upper(), 
                     "class": var_class,
                     "edit": False,
                     "debug": True}
         else:
             return {"name": variable.getname(),
-                    "type": vartype_content["name"], 
+                    "type": vartype_content_type, 
                     "class": var_class,
                     "edit": False,
                     "debug": True}
@@ -558,9 +561,9 @@
         for varlist in varlists:
             for variable in varlist.getvariable():
                 vartype_content = variable.gettype().getcontent()
-                if vartype_content["name"] == "derived":
+                if vartype_content.getLocalTag() == "derived":
                     var_path = "%s.%s" % (parent_path, variable.getname())
-                    var_type = vartype_content["value"].getname()
+                    var_type = vartype_content.getname()
                     if var_type == pou_type:
                         instances.append(var_path)
                     else:
@@ -627,7 +630,7 @@
                 for variable in varlist.getvariable():
                     if variable.getname() == parts[0]:
                         vartype_content = variable.gettype().getcontent()
-                        if vartype_content["name"] == "derived":
+                        if vartype_content.getLocalTag() == "derived":
                             return self.RecursiveGetPouInstanceTagName(
                                             project, 
                                             vartype_content["value"].getname(),
@@ -658,14 +661,14 @@
             for variable in varlist.getvariable():
                 if variable.getname() == parts[0]:
                     vartype_content = variable.gettype().getcontent()
-                    if vartype_content["name"] == "derived":                        
+                    if vartype_content.getLocalTag() == "derived":                        
                         if len(parts) == 1:
                             return self.ComputePouName(
-                                        vartype_content["value"].getname())
+                                        vartype_content.getname())
                         else:
                             return self.RecursiveGetPouInstanceTagName(
                                         project, 
-                                        vartype_content["value"].getname(),
+                                        vartype_content.getname(),
                                         parts[1:], debug)
         return None
     
@@ -1172,9 +1175,9 @@
                 current_type = next_type
                 infos = VAR_CLASS_INFOS.get(var["Class"], None)
                 if infos is not None:
-                    current_varlist = infos[0]()
+                    current_varlist = PLCOpenParser.CreateElement(infos[0], "interface")
                 else:
-                    current_varlist = plcopen.varList()
+                    current_varlist = PLCOpenParser.CreateElement("varList")
                 varlist_list.append((var["Class"], current_varlist))
                 if var["Option"] == "Constant":
                     current_varlist.setconstant(True)
@@ -1183,14 +1186,14 @@
                 elif var["Option"] == "Non-Retain":
                     current_varlist.setnonretain(True)
             # Create variable and change its properties
-            tempvar = plcopen.varListPlain_variable()
+            tempvar = PLCOpenParser.CreateElement("variable", "varListPlain")
             tempvar.setname(var["Name"])
             
-            var_type = plcopen.dataType()
+            var_type = PLCOpenParser.CreateElement("type", "variable")
             if isinstance(var["Type"], TupleType):
                 if var["Type"][0] == "array":
                     array_type, base_type_name, dimensions = var["Type"]
-                    array = plcopen.derivedTypes_array()
+                    array = PLCOpenParser.CreateElement("array", "dataType")
                     for i, dimension in enumerate(dimensions):
                         dimension_range = plcopen.rangeSigned()
                         dimension_range.setlower(dimension[0])
@@ -1200,32 +1203,28 @@
                         else:
                             array.appenddimension(dimension_range)
                     if base_type_name in self.GetBaseTypes():
-                        if base_type_name == "STRING":
-                            array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                        elif base_type_name == "WSTRING":
-                            array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
-                        else:
-                            array.baseType.setcontent({"name" : base_type_name, "value" : None})
+                        array.baseType.setcontent(PLCOpenParser.CreateElement(
+                            base_type_name.lower()
+                            if base_type_name in ["STRING", "WSTRING"]
+                            else base_type_name, "dataType"))
                     else:
-                        derived_datatype = plcopen.derivedTypes_derived()
+                        derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                         derived_datatype.setname(base_type_name)
-                        array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
-                    var_type.setcontent({"name" : "array", "value" : array})
+                        array.baseType.setcontent(derived_datatype)
+                    var_type.setcontent(array)
             elif var["Type"] in self.GetBaseTypes():
-                if var["Type"] == "STRING":
-                    var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                elif var["Type"] == "WSTRING":
-                    var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
-                else:
-                    var_type.setcontent({"name" : var["Type"], "value" : None})
+                var_type.setcontent(PLCOpenParser.CreateElement(
+                    var["Type"].lower()
+                    if var["Type"] in ["STRING", "WSTRING"]
+                    else var["Type"], "dataType"))
             else:
-                derived_type = plcopen.derivedTypes_derived()
+                derived_type = PLCOpenParser.CreateElement("derived", "dataType")
                 derived_type.setname(var["Type"])
-                var_type.setcontent({"name" : "derived", "value" : derived_type})
+                var_type.setcontent(derived_type)
             tempvar.settype(var_type)
 
             if var["Initial Value"] != "":
-                value = plcopen.value()
+                value = PLCOpenParser.CreateElement("initialValue", "variable")
                 value.setvalue(var["Initial Value"])
                 tempvar.setinitialValue(value)
             if var["Location"] != "":
@@ -1234,7 +1233,7 @@
                 tempvar.setaddress(None)
             if var['Documentation'] != "":
                 ft = plcopen.formattedText()
-                ft.settext(var['Documentation'])
+                ft.setanyText(var['Documentation'])
                 tempvar.setdocumentation(ft)
 
             # Add variable to varList
@@ -1250,27 +1249,27 @@
         tempvar = {"Name": var.getname()}
 
         vartype_content = var.gettype().getcontent()
-        if vartype_content["name"] == "derived":
-            tempvar["Type"] = vartype_content["value"].getname()
-        elif vartype_content["name"] == "array":
+        vartype_content_type = vartype_content.getLocalTag()
+        if vartype_content_type == "derived":
+            tempvar["Type"] = vartype_content.getname()
+        elif vartype_content_type == "array":
             dimensions = []
-            for dimension in vartype_content["value"].getdimension():
+            for dimension in vartype_content.getdimension():
                 dimensions.append((dimension.getlower(), dimension.getupper()))
-            base_type = vartype_content["value"].baseType.getcontent()
-            if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
-                base_type_name = base_type["name"].upper()
+            base_type = vartype_content.baseType.getcontent()
+            base_type_type = base_type.getLocalTag()
+            if base_type is None or base_type_type in ["string", "wstring"]:
+                base_type_name = base_type_type.upper()
             else:
-                base_type_name = base_type["value"].getname()
+                base_type_name = base_type.getname()
             tempvar["Type"] = ("array", base_type_name, dimensions)
-        elif vartype_content["name"] in ["string", "wstring"]:
-            tempvar["Type"] = vartype_content["name"].upper()
         else:
-            tempvar["Type"] = vartype_content["name"]
-
+            tempvar["Type"] = vartype_content_type.upper()
+        
         tempvar["Edit"] = True
 
         initial = var.getinitialValue()
-        if initial:
+        if initial is not None:
             tempvar["Initial Value"] = initial.getvalue()
         else:
             tempvar["Initial Value"] = ""
@@ -1291,8 +1290,8 @@
             tempvar["Option"] = ""
 
         doc = var.getdocumentation()
-        if doc:
-            tempvar["Documentation"] = doc.gettext()
+        if doc is not None:
+            tempvar["Documentation"] = doc.getanyText()
         else:
             tempvar["Documentation"] = ""
 
@@ -1315,9 +1314,9 @@
             configuration = self.Project.getconfiguration(name)
             if configuration is not None:
                 # Set configuration global vars
-                configuration.setglobalVars([])
-                for vartype, varlist in self.ExtractVarLists(vars):
-                    configuration.globalVars.append(varlist)
+                configuration.setglobalVars([
+                    varlist for vartype, varlist
+                    in self.ExtractVarLists(vars)])
     
     # Return the configuration globalvars
     def GetConfigurationGlobalVars(self, name, debug = False):
@@ -1356,9 +1355,9 @@
             resource = self.Project.getconfigurationResource(config_name, name)
             # Set resource global vars
             if resource is not None:
-                resource.setglobalVars([])
-                for vartype, varlist in self.ExtractVarLists(vars):
-                    resource.globalVars.append(varlist)
+                resource.setglobalVars([
+                    varlist for vartype, varlist
+                    in self.ExtractVarLists(vars)])
     
     # Return the resource globalvars
     def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
@@ -1417,25 +1416,27 @@
             if datatype is not None:
                 tree = []
                 basetype_content = datatype.baseType.getcontent()
-                if basetype_content["name"] == "derived":
-                    return self.GenerateVarTree(basetype_content["value"].getname())
-                elif basetype_content["name"] == "array":
+                basetype_content_type = basetype_content.getLocalTag()
+                if basetype_content_type == "derived":
+                    return self.GenerateVarTree(basetype_content.getname())
+                elif basetype_content_type == "array":
                     dimensions = []
-                    base_type = basetype_content["value"].baseType.getcontent()
-                    if base_type["name"] == "derived":
-                        tree = self.GenerateVarTree(base_type["value"].getname())
+                    base_type = basetype_content.baseType.getcontent()
+                    if base_type.getLocalTag() == "derived":
+                        tree = self.GenerateVarTree(base_type.getname())
                         if len(tree[1]) == 0:
                             tree = tree[0]
-                        for dimension in basetype_content["value"].getdimension():
+                        for dimension in basetype_content.getdimension():
                             dimensions.append((dimension.getlower(), dimension.getupper()))
                     return tree, dimensions
-                elif basetype_content["name"] == "struct":
-                    for element in basetype_content["value"].getvariable():
+                elif basetype_content_type == "struct":
+                    for element in basetype_content.getvariable():
                         element_type = element.type.getcontent()
-                        if element_type["name"] == "derived":
-                            tree.append((element.getname(), element_type["value"].getname(), self.GenerateVarTree(element_type["value"].getname())))
+                        element_type_type = element_type.getLocalTag()
+                        if element_type_type == "derived":
+                            tree.append((element.getname(), element_type.getname(), self.GenerateVarTree(element_type.getname())))
                         else:
-                            tree.append((element.getname(), element_type["name"], ([], [])))
+                            tree.append((element.getname(), element_type_type, ([], [])))
                     return tree, []
         return [], []
 
@@ -1453,7 +1454,7 @@
                     tempvar["Tree"] = ([], [])
 
                     vartype_content = var.gettype().getcontent()
-                    if vartype_content["name"] == "derived":
+                    if vartype_content.getLocalTag() == "derived":
                         tempvar["Edit"] = not pou.hasblock(tempvar["Name"])
                         tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug)
 
@@ -1467,36 +1468,34 @@
             pou = self.Project.getpou(name)
             if pou is not None:
                 if pou.interface is None:
-                    pou.interface = plcopen.pou_interface()
+                    pou.interface = PLCOpenParser.CreateElement("interface", "pou")
                 # Set Pou interface
-                pou.setvars(self.ExtractVarLists(vars))
+                pou.setvars([varlist for varlist_type, varlist in self.ExtractVarLists(vars)])
                 self.Project.RefreshElementUsingTree()
                 self.Project.RefreshCustomBlockTypes()
     
     # Replace the return type of the pou given by its name (only for functions)
-    def SetPouInterfaceReturnType(self, name, type):
+    def SetPouInterfaceReturnType(self, name, return_type):
         if self.Project is not None:
             pou = self.Project.getpou(name)
             if pou is not None:
                 if pou.interface is None:
-                    pou.interface = plcopen.pou_interface()
+                    pou.interface = PLCOpenParser.CreateElement("interface", "pou")
                 # If there isn't any return type yet, add it
-                return_type = pou.interface.getreturnType()
-                if not return_type:
-                    return_type = plcopen.dataType()
-                    pou.interface.setreturnType(return_type)
+                return_type_obj = pou.interface.getreturnType()
+                if not return_type_obj:
+                    return_type_obj = PLCOpenParser.CreateElement("returnType", "interface")
+                    pou.interface.setreturnType(return_type_obj)
                 # Change return type
-                if type in self.GetBaseTypes():
-                    if type == "STRING":
-                        return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                    elif type == "WSTRING":
-                        return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
-                    else:
-                        return_type.setcontent({"name" : type, "value" : None})
+                if return_type in self.GetBaseTypes():
+                    return_type_obj.setcontent(PLCOpenParser.CreateElement(
+                        return_type.lower()
+                        if return_type in ["STRING", "WSTRING"]
+                        else return_type, "dataType"))
                 else:
-                    derived_type = plcopen.derivedTypes_derived()
-                    derived_type.setname(type)
-                    return_type.setcontent({"name" : "derived", "value" : derived_type})
+                    derived_type = PLCOpenParser.CreateElement("derived", "dataType")
+                    derived_type.setname(return_type)
+                    return_type.setcontent(derived_type)
                 self.Project.RefreshElementUsingTree()
                 self.Project.RefreshCustomBlockTypes()
     
@@ -1525,14 +1524,13 @@
         if pou.interface is not None:
             # Return the return type if there is one
             return_type = pou.interface.getreturnType()
-            if return_type:
+            if return_type is not None:
                 returntype_content = return_type.getcontent()
-                if returntype_content["name"] == "derived":
-                    return returntype_content["value"].getname()
-                elif returntype_content["name"] in ["string", "wstring"]:
-                    return returntype_content["name"].upper()
+                returntype_content_type = returntype_content.getLocalTag()
+                if returntype_content_type == "derived":
+                    return returntype_content.getname()
                 else:
-                    return returntype_content["name"]
+                    return returntype_content_type.upper()
         return None
 
     # Function that add a new confnode to the confnode list
@@ -1579,25 +1577,23 @@
     def GetConfigurationExtraVariables(self):
         global_vars = []
         for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
-            tempvar = plcopen.varListPlain_variable()
+            tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
             tempvar.setname(var_name)
             
-            tempvartype = plcopen.dataType()
+            tempvartype = PLCOpenParser.CreateElement("dataType", "variable")
             if var_type in self.GetBaseTypes():
-                if var_type == "STRING":
-                    tempvartype.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                elif var_type == "WSTRING":
-                    tempvartype.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
-                else:
-                    tempvartype.setcontent({"name" : var_type, "value" : None})
+                tempvar.setcontent(PLCOpenParser.CreateElement(
+                    var_type.lower()
+                    if var_type in ["STRING", "WSTRING"]
+                    else var_type, "dataType"))
             else:
-                tempderivedtype = plcopen.derivedTypes_derived()
+                tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
                 tempderivedtype.setname(var_type)
-                tempvartype.setcontent({"name" : "derived", "value" : tempderivedtype})
+                tempvartype.setcontent(tempderivedtype)
             tempvar.settype(tempvartype)
             
             if var_initial != "":
-                value = plcopen.value()
+                value = PLCOpenParser.CreateElement("initialValue", "variable")
                 value.setvalue(var_initial)
                 tempvar.setinitialValue(value)
             
@@ -1766,7 +1762,7 @@
                 datatype = self.GetConfNodeDataType(type)
             if datatype is not None:
                 basetype_content = datatype.baseType.getcontent()
-                return basetype_content["name"] == "enum"
+                return basetype_content.getLocalTag() == "enum"
         return False
 
     def IsNumType(self, type, debug = False):
@@ -1861,62 +1857,64 @@
                 if datatype is None:
                     return None
                 basetype_content = datatype.baseType.getcontent()
-                if basetype_content["value"] is None or basetype_content["name"] in ["string", "wstring"]:
-                    infos["type"] = "Directly"
-                    infos["base_type"] = basetype_content["name"].upper()
-                elif basetype_content["name"] == "derived":
-                    infos["type"] = "Directly"
-                    infos["base_type"] = basetype_content["value"].getname()
-                elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
+                basetype_content_type = basetype_content.getLocalTag()
+                if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
                     infos["type"] = "Subrange"
-                    infos["min"] = basetype_content["value"].range.getlower()
-                    infos["max"] = basetype_content["value"].range.getupper()
-                    base_type = basetype_content["value"].baseType.getcontent()
-                    if base_type["value"] is None:
-                        infos["base_type"] = base_type["name"]
-                    else:
-                        infos["base_type"] = base_type["value"].getname()
-                elif basetype_content["name"] == "enum":
+                    infos["min"] = basetype_content.range.getlower()
+                    infos["max"] = basetype_content.range.getupper()
+                    base_type = basetype_content.baseType.getcontent()
+                    base_type_type = base_type.getLocalTag()
+                    infos["base_type"] = (base_type.getname()
+                        if base_type_type == "derived"
+                        else base_type_type)
+                elif basetype_content_type == "enum":
                     infos["type"] = "Enumerated"
                     infos["values"] = []
-                    for value in basetype_content["value"].values.getvalue():
+                    for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP):
                         infos["values"].append(value.getname())
-                elif basetype_content["name"] == "array":
+                elif basetype_content_type == "array":
                     infos["type"] = "Array"
                     infos["dimensions"] = []
-                    for dimension in basetype_content["value"].getdimension():
+                    for dimension in basetype_content.getdimension():
                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
-                    base_type = basetype_content["value"].baseType.getcontent()
-                    if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
-                        infos["base_type"] = base_type["name"].upper()
-                    else:
-                        infos["base_type"] = base_type["value"].getname()
-                elif basetype_content["name"] == "struct":
+                    base_type = basetype_content.baseType.getcontent()
+                    base_type_type = base_type.getLocalTag()
+                    infos["base_type"] = (base_type.getname()
+                        if base_type_type == "derived"
+                        else base_type_type.upper())
+                elif basetype_content_type == "struct":
                     infos["type"] = "Structure"
                     infos["elements"] = []
-                    for element in basetype_content["value"].getvariable():
+                    for element in basetype_content.getvariable():
                         element_infos = {}
                         element_infos["Name"] = element.getname()
                         element_type = element.type.getcontent()
-                        if element_type["value"] is None or element_type["name"] in ["string", "wstring"]:
-                            element_infos["Type"] = element_type["name"].upper()
-                        elif element_type["name"] == "array":
+                        element_type_type = element_type.getLocalTag()
+                        if element_type_type == "array":
                             dimensions = []
-                            for dimension in element_type["value"].getdimension():
+                            for dimension in element_type.getdimension():
                                 dimensions.append((dimension.getlower(), dimension.getupper()))
-                            base_type = element_type["value"].baseType.getcontent()
-                            if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
-                                base_type_name = base_type["name"].upper()
-                            else:
-                                base_type_name = base_type["value"].getname()
-                            element_infos["Type"] = ("array", base_type_name, dimensions)
+                            base_type = element_type.baseType.getcontent()
+                            base_type_type = element_type.getLocalTag()
+                            element_infos["Type"] = ("array", 
+                                base_type.getname()
+                                if base_type_type == "derived"
+                                else base_type_type.upper(), dimensions)
+                        elif element_type_type == "derived":
+                            element_infos["Type"] = element_type.getname()
                         else:
-                            element_infos["Type"] = element_type["value"].getname()
+                            element_infos["Type"] = element_type_type.upper()
                         if element.initialValue is not None:
                             element_infos["Initial Value"] = str(element.initialValue.getvalue())
                         else:
                             element_infos["Initial Value"] = ""
                         infos["elements"].append(element_infos)
+                else:
+                    infos["type"] = "Directly"
+                    infos["base_type"] = (basetype_content.getname()
+                        if basetype_content_type == "derived"
+                        else basetype_content_type.upper())
+                
                 if datatype.initialValue is not None:
                     infos["initial"] = str(datatype.initialValue.getvalue())
                 else:
@@ -1931,45 +1929,44 @@
             datatype = self.Project.getdataType(words[1])
             if infos["type"] == "Directly":
                 if infos["base_type"] in self.GetBaseTypes():
-                    if infos["base_type"] == "STRING":
-                        datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                    elif infos["base_type"] == "WSTRING":
-                        datatype.baseType.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
-                    else:
-                        datatype.baseType.setcontent({"name" : infos["base_type"], "value" : None})
+                    datatype.baseType.setcontent(PLCOpenParser.CreateElement(
+                        infos["base_type"].lower()
+                        if infos["base_type"] in ["STRING", "WSTRING"]
+                        else infos["base_type"], "dataType"))
                 else:
-                    derived_datatype = plcopen.derivedTypes_derived()
+                    derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                     derived_datatype.setname(infos["base_type"])
-                    datatype.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
+                    datatype.baseType.setcontent(derived_datatype)
             elif infos["type"] == "Subrange":
-                if infos["base_type"] in GetSubTypes("ANY_UINT"):
-                    subrange = plcopen.derivedTypes_subrangeUnsigned()
-                    datatype.baseType.setcontent({"name" : "subrangeUnsigned", "value" : subrange})
-                else:
-                    subrange = plcopen.derivedTypes_subrangeSigned()
-                    datatype.baseType.setcontent({"name" : "subrangeSigned", "value" : subrange})
+                datatype.baseType.setcontent(PLCOpenParser.CreateElement(
+                    "subrangeUnsigned" 
+                    if infos["base_type"] in GetSubTypes("ANY_UINT")
+                    else "subrangeSigned", "dataType"))
                 subrange.range.setlower(infos["min"])
                 subrange.range.setupper(infos["max"])
                 if infos["base_type"] in self.GetBaseTypes():
-                    subrange.baseType.setcontent({"name" : infos["base_type"], "value" : None})
+                    subrange.baseType.setcontent(
+                        PLCOpenParser.CreateElement(infos["base_type"]))
                 else:
-                    derived_datatype = plcopen.derivedTypes_derived()
+                    derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                     derived_datatype.setname(infos["base_type"])
-                    subrange.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
+                    subrange.baseType.setcontent(derived_datatype)
             elif infos["type"] == "Enumerated":
-                enumerated = plcopen.derivedTypes_enum()
+                enumerated = PLCOpenParser.CreateElement("enum", "dataType")
+                values = PLCOpenParser.CreateElement("values", "enum")
+                enumerated.setvalues(values)
                 for i, enum_value in enumerate(infos["values"]):
-                    value = plcopen.values_value()
+                    value = PLCOpenParser.CreateElement("value", "values")
                     value.setname(enum_value)
                     if i == 0:
-                        enumerated.values.setvalue([value])
+                        values.setvalue([value])
                     else:
-                        enumerated.values.appendvalue(value)
-                datatype.baseType.setcontent({"name" : "enum", "value" : enumerated})
+                        values.appendvalue(value)
+                datatype.baseType.setcontent(enumerated)
             elif infos["type"] == "Array":
-                array = plcopen.derivedTypes_array()
+                array = PLCOpenParser.CreateElement("array", "dataType")
                 for i, dimension in enumerate(infos["dimensions"]):
-                    dimension_range = plcopen.rangeSigned()
+                    dimension_range = PLCOpenParser.CreateElement("dimension", "array")
                     dimension_range.setlower(dimension[0])
                     dimension_range.setupper(dimension[1])
                     if i == 0:
@@ -1977,28 +1974,27 @@
                     else:
                         array.appenddimension(dimension_range)
                 if infos["base_type"] in self.GetBaseTypes():
-                    if infos["base_type"] == "STRING":
-                        array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                    elif infos["base_type"] == "WSTRING":
-                        array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
-                    else:
-                        array.baseType.setcontent({"name" : infos["base_type"], "value" : None})
+                    array.baseType.setcontent(PLCOpenParser.CreateElement(
+                        infos["base_type"].lower()
+                        if infos["base_type"] in ["STRING", "WSTRING"]
+                        else infos["base_type"], "dataType"))
                 else:
-                    derived_datatype = plcopen.derivedTypes_derived()
+                    derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                     derived_datatype.setname(infos["base_type"])
-                    array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
-                datatype.baseType.setcontent({"name" : "array", "value" : array})
+                    array.baseType.setcontent(derived_datatype)
+                datatype.baseType.setcontent(array)
             elif infos["type"] == "Structure":
-                struct = plcopen.varListPlain()
+                struct = PLCOpenParser.CreateElement("struct", "dataType")
                 for i, element_infos in enumerate(infos["elements"]):
-                    element = plcopen.varListPlain_variable()
+                    element = PLCOpenParser.CreateElement("variable", "struct")
                     element.setname(element_infos["Name"])
+                    element_type = PLCOpenParser.CreateElement("type", "variable")
                     if isinstance(element_infos["Type"], TupleType):
                         if element_infos["Type"][0] == "array":
                             array_type, base_type_name, dimensions = element_infos["Type"]
-                            array = plcopen.derivedTypes_array()
+                            array = PLCOpenParser.CreateElement("array", "dataType")
                             for j, dimension in enumerate(dimensions):
-                                dimension_range = plcopen.rangeSigned()
+                                dimension_range = PLCOpenParser.CreateElement("dimension", "array")
                                 dimension_range.setlower(dimension[0])
                                 dimension_range.setupper(dimension[1])
                                 if j == 0:
@@ -2006,40 +2002,38 @@
                                 else:
                                     array.appenddimension(dimension_range)
                             if base_type_name in self.GetBaseTypes():
-                                if base_type_name == "STRING":
-                                    array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                                elif base_type_name == "WSTRING":
-                                    array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
-                                else:
-                                    array.baseType.setcontent({"name" : base_type_name, "value" : None})
+                                array.baseType.setcontent(PLCOpenParser.CreateElement(
+                                    base_type_name.lower()
+                                    if base_type_name in ["STRING", "WSTRING"]
+                                    else base_type_name, "dataType"))
                             else:
-                                derived_datatype = plcopen.derivedTypes_derived()
+                                derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                                 derived_datatype.setname(base_type_name)
-                                array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
-                            element.type.setcontent({"name" : "array", "value" : array})
+                                array.baseType.setcontent(derived_datatype)
+                            element_type.setcontent(array)
                     elif element_infos["Type"] in self.GetBaseTypes():
-                        if element_infos["Type"] == "STRING":
-                            element.type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-                        elif element_infos["Type"] == "WSTRING":
-                            element.type.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
-                        else:
-                            element.type.setcontent({"name" : element_infos["Type"], "value" : None})
+                        element_type.setcontent(
+                            PLCOpenParser.CreateElement(
+                                element_infos["Type"].lower()
+                                if element_infos["Type"] in ["STRING", "WSTRING"]
+                                else element_infos["Type"], "dataType"))
                     else:
-                        derived_datatype = plcopen.derivedTypes_derived()
+                        derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
                         derived_datatype.setname(element_infos["Type"])
-                        element.type.setcontent({"name" : "derived", "value" : derived_datatype})
+                        element_type.setcontent(derived_datatype)
+                    element.settype(element_type)
                     if element_infos["Initial Value"] != "":
-                        value = plcopen.value()
+                        value = PLCOpenParser.CreateElement("initialValue", "variable")
                         value.setvalue(element_infos["Initial Value"])
                         element.setinitialValue(value)
                     if i == 0:
                         struct.setvariable([element])
                     else:
                         struct.appendvariable(element)
-                datatype.baseType.setcontent({"name" : "struct", "value" : struct})
+                datatype.baseType.setcontent(struct)
             if infos["initial"] != "":
                 if datatype.initialValue is None:
-                    datatype.initialValue = plcopen.value()
+                    datatype.initialValue = PLCOpenParser.CreateElement("initialValue", "dataType")
                 datatype.initialValue.setvalue(infos["initial"])
             else:
                 datatype.initialValue = None
@@ -2203,9 +2197,10 @@
                 element = self.GetEditedElement(tagname, debug)
                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
                     for instance in element.getinstances():
-                        if isinstance(instance, (plcopen.sfcObjects_step, 
-                                                 plcopen.commonObjects_connector, 
-                                                 plcopen.commonObjects_continuation)):
+                        if isinstance(instance, 
+                            (PLCOpenParser.GetElementClass("step", "sfcObjects"), 
+                             PLCOpenParser.GetElementClass("connector", "commonObjects"), 
+                             PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
                             names[instance.getname().upper()] = True
         else:
             project = self.GetProject(debug)
@@ -2394,12 +2389,11 @@
                         for var in varlist.getvariable():
                             if var.getname() == varname:
                                 vartype_content = var.gettype().getcontent()
-                                if vartype_content["name"] == "derived":
-                                    return vartype_content["value"].getname()
-                                elif vartype_content["name"] in ["string", "wstring"]:
-                                    return vartype_content["name"].upper()
+                                vartype_content_type = vartype_content.getLocalTag()
+                                if vartype_content_type == "derived":
+                                    return vartype_content.getname()
                                 else:
-                                    return vartype_content["name"]
+                                    return vartype_content_type.upper()
         return None
     
     def SetConnectionWires(self, connection, connector):
@@ -2459,7 +2453,7 @@
     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
         element = self.GetEditedElement(tagname)
         if element is not None:
-            block = plcopen.fbdObjects_block()
+            block = PLCOpenParser.CreateElement("block", "fbdObjects")
             block.setlocalId(id)
             block.settypeName(blocktype)
             blocktype_infos = self.GetBlockType(blocktype)
--- a/plcopen/plcopen.py	Mon Aug 26 10:55:03 2013 +0200
+++ b/plcopen/plcopen.py	Wed Aug 28 11:52:46 2013 +0200
@@ -186,7 +186,7 @@
     setattr(cls, "hasblock", hasblock)
     
     def Search(self, criteria, parent_infos):
-        return [(tuple(parent_infos),) + result for result in TestTextElement(self.gettext(), criteria)]
+        return [(tuple(parent_infos),) + result for result in TestTextElement(self.getanyText(), criteria)]
     setattr(cls, "Search", Search)
     
 cls = PLCOpenParser.GetElementClass("project")
@@ -473,9 +473,9 @@
         block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False,
                        "inputs" : [], "outputs" : [], "comment" : pou.getdescription(),
                        "generate" : generate_block, "initialise" : initialise_block}
-        if pou.getinterface():
+        if pou.interface is not None:
             return_type = pou.interface.getreturnType()
-            if return_type:
+            if return_type is not None:
                 var_type = return_type.getcontent()
                 var_type_name = var_type.getLocalTag()
                 if var_type_name == "derived":
@@ -553,7 +553,7 @@
         # Analyze each pou
         for pou in self.getpous():
             name = pou.getname()
-            if pou.interface:
+            if pou.interface is not None:
                 # Extract variables from every varLists
                 for varlist_type, varlist in pou.getvars():
                     for var in varlist.getvariable():
@@ -869,14 +869,11 @@
         var.setname(name)
         var_type_obj = PLCOpenParser.CreateElement("dataType")
         if var_type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]:
-            if var_type == "STRING":
-                var_type_obj.setcontent(PLCOpenParser.CreateElement("string", "elementaryTypes"))
-            elif var_type == "WSTRING":
-                var_type_obj.setcontent(PLCOpenParser.CreateElement("wstring", "elementaryTypes"))
-            else:
-                var_type_obj.setcontent(PLCOpenParser.CreateElement(var_type))
+            var_type_obj.setcontent(PLCOpenParser.CreateElement(
+                var_type.lower() if var_type in ["STRING", "WSTRING"]
+                else vartype, "dataType"))
         else:
-            derived_type = PLCOpenParser.CreateElement("derived", "derivedTypes")
+            derived_type = PLCOpenParser.CreateElement("derived", "dataType")
             derived_type.setname(var_type)
             var_type_obj.setcontent(derived_type)
         var.settype(var_type_obj)
@@ -884,7 +881,7 @@
             var.setaddress(location)
         if description != "":
             ft = PLCOpenParser.CreateElementClass("formattedText")
-            ft.settext(description)
+            ft.setanyText(description)
             var.setdocumentation(ft)
         globalvars[-1].appendvariable(var)
     setattr(cls, "addglobalVar", addglobalVar)
@@ -1197,7 +1194,7 @@
         return search_result
     setattr(cls, "Search", Search)
 
-cls = PLCOpenParser.GetElementClass("array", "derivedTypes")
+cls = PLCOpenParser.GetElementClass("array", "dataType")
 if cls:
     setattr(cls, "updateElementName", _updateBaseTypeElementName)
     
@@ -1217,17 +1214,17 @@
                                  criteria, parent_infos))
     return search_result
 
-cls = PLCOpenParser.GetElementClass("subrangeSigned", "derivedTypes")
+cls = PLCOpenParser.GetElementClass("subrangeSigned", "dataType")
 if cls:
     setattr(cls, "updateElementName", _updateBaseTypeElementName)
     setattr(cls, "Search", _SearchInSubrange)
 
-cls = PLCOpenParser.GetElementClass("subrangeUnsigned", "derivedTypes")
+cls = PLCOpenParser.GetElementClass("subrangeUnsigned", "dataType")
 if cls:
     setattr(cls, "updateElementName", _updateBaseTypeElementName)
     setattr(cls, "Search", _SearchInSubrange)
 
-cls = PLCOpenParser.GetElementClass("enum", "derivedTypes")
+cls = PLCOpenParser.GetElementClass("enum", "dataType")
 if cls:
     
     def updateElementName(self, old_name, new_name):
@@ -1250,13 +1247,13 @@
         if doc is None:
             doc = PLCOpenParser.CreateElement("formattedText")
             self.setdocumentation(doc)
-        doc.settext(description)
+        doc.setanyText(description)
     setattr(cls, "setdescription", setdescription)
     
     def getdescription(self):
         doc = self.getdocumentation()
         if doc is not None:
-            return doc.gettext()
+            return doc.getanyText()
         return ""
     setattr(cls, "getdescription", getdescription)
     
@@ -1348,6 +1345,7 @@
         if self.interface is None:
             self.interface = PLCOpenParser.CreateElement("interface", "pou")
         self.interface.setcontent(vars)
+        print self.interface.tostring()
     setattr(cls, "setvars", setvars)
     
     def addpouLocalVar(self, var_type, name, location="", description=""):
@@ -1373,14 +1371,11 @@
         var.setname(name)
         var_type_obj = PLCOpenParser.CreateElement("dataType")
         if var_type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]:
-            if var_type == "STRING":
-                var_type_obj.setcontent(PLCOpenParser.CreateElement("string", "elementaryTypes"))
-            elif var_type == "WSTRING":
-                var_type_obj.setcontent(PLCOpenParser.CreateElement("wstring", "elementaryTypes"))
-            else:
-                var_type_obj.setcontent(PLCOpenParser.CreateElement(var_type))
+            var_type_obj.setcontent(PLCOpenParser.CreateElement(
+                var_type.lower() if var_type in ["STRING", "WSTRING"]
+                else var_type, "dataType"))
         else:
-            derived_type = PLCOpenParser.CreateElement("derived", "derivedTypes")
+            derived_type = PLCOpenParser.CreateElement("derived", "dataType")
             derived_type.setname(var_type)
             var_type_obj.setcontent(derived_type)
         var.settype(var_type_obj)
@@ -1388,7 +1383,7 @@
             var.setaddress(location)
         if description != "":
             ft = PLCOpenParser.GetElementClass("formattedText")()
-            ft.settext(description)
+            ft.setanyText(description)
             var.setdocumentation(ft)
         
         content[-1]["value"].appendvariable(var)
@@ -1453,9 +1448,9 @@
         transition.setname(name)
         transition.setbodyType(body_type)
         if body_type == "ST":
-            transition.settext(":= ;")
+            transition.setanyText(":= ;")
         elif body_type == "IL":
-            transition.settext("\tST\t%s"%name)
+            transition.setanyText("\tST\t%s"%name)
         self.transitions.appendtransition(transition)
     setattr(cls, "addtransition", addtransition)
     
@@ -1832,7 +1827,10 @@
     
     def getcontentRandomInstance(self, exclude):
         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
-            instance = self.content.xpath("*[regexp:test(@localId,'(%s)')]" % "|".join(map(str, exclude)))
+            instance = self.content.xpath("*%s[position()=1]" %  
+                ("[not(%s)]" % " or ".join(
+                    map(lambda x: "@localId=%d" % x, exclude))
+                if len(exclude) > 0 else ""))
             if len(instance) > 0:
                 return instance[0]
             return None
@@ -1863,14 +1861,14 @@
     
     def settext(self, text):
         if self.content.getLocalTag() in ["IL","ST"]:
-            self.content.settext(text)
+            self.content.setanyText(text)
         else:
             raise TypeError, _("%s body don't have text!")%self.content["name"]
     setattr(cls, "settext", settext)
 
     def gettext(self):
         if self.content.getLocalTag() in ["IL","ST"]:
-            return self.content.gettext()
+            return self.content.getanyText()
         else:
             raise TypeError, _("%s body don't have text!")%self.content["name"]
     setattr(cls, "gettext", gettext)
@@ -2103,7 +2101,7 @@
         infos = _getelementinfos(self)
         infos["type"] = type
         specific_values = infos["specific_values"]
-        specific_values["name"] = self.getexpression()
+        specific_values["name"] = self.getexpression().text
         _getexecutionOrder(self, specific_values)
         if input and output:
             infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input"))
@@ -2116,7 +2114,7 @@
     return getvariableinfos
 
 def _getconnectorinfosFunction(type):
-    def getvariableinfos(self):
+    def getconnectorinfos(self):
         infos = _getelementinfos(self)
         infos["type"] = type
         infos["specific_values"]["name"] = self.getname()
@@ -2125,7 +2123,7 @@
         elif type == "continuation":
             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
         return infos
-    return getvariableinfos
+    return getconnectorinfos
 
 def _getpowerrailinfosFunction(type):
     def getpowerrailinfos(self):
@@ -2190,11 +2188,11 @@
     setattr(cls, "getinfos", getinfos)
     
     def setcontentText(self, text):
-        self.content.settext(text)
+        self.content.setanyText(text)
     setattr(cls, "setcontentText", setcontentText)
         
     def getcontentText(self):
-        return self.content.gettext()
+        return self.content.getanyText()
     setattr(cls, "getcontentText", getcontentText)
     
     def updateElementName(self, old_name, new_name):
@@ -2378,7 +2376,7 @@
         elif condition_type == "inline":
             condition = PLCOpenParser.CreateElement("inline", "condition")
             condition.setcontent(PLCOpenParser.GetElementClass("ST", "inline"))
-            condition.settext(value)
+            condition.setanyText(value)
         elif condition_type == "connection":
             condition = PLCOpenParser.CreateElementClass("connectionPointIn")
         self.condition.setcontent(condition)
@@ -2391,7 +2389,7 @@
             if values["type"] == "reference":
                 values["value"] = content.getname()
             elif values["type"] == "inline":
-                values["value"] = content.gettext()
+                values["value"] = content.getanyText()
             elif values["type"] == "connectionPointIn":
                 values["type"] = "connection"
                 values["value"] = content
@@ -2479,23 +2477,23 @@
         return search_result
     setattr(cls, "Search", Search)
     
-cls = _initElementClass("selectionDivergence", "sfcObjects_selectionDivergence", "single")
+cls = _initElementClass("selectionDivergence", "sfcObjects", "single")
 if cls:
     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False))
 
-cls = _initElementClass("selectionConvergence", "sfcObjects_selectionConvergence", "multiple")
+cls = _initElementClass("selectionConvergence", "sfcObjects", "multiple")
 if cls:
     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False))
 
-cls = _initElementClass("simultaneousDivergence", "sfcObjects_simultaneousDivergence", "single")
+cls = _initElementClass("simultaneousDivergence", "sfcObjects", "single")
 if cls:
     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True))
 
-cls = _initElementClass("simultaneousConvergence", "sfcObjects_simultaneousConvergence", "multiple")
+cls = _initElementClass("simultaneousConvergence", "sfcObjects", "multiple")
 if cls:
     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True))
 
-cls = _initElementClass("jumpStep", "sfcObjects_jumpStep", "single")
+cls = _initElementClass("jumpStep", "sfcObjects", "single")
 if cls:
     def getinfos(self):
         infos = _getelementinfos(self)
@@ -2536,12 +2534,12 @@
     def setinlineContent(self, content):
         if self.inline:
             self.inline.setcontent(PLCOpenParser.CreateElementClass("ST", "action"))
-            self.inline.settext(content)
+            self.inline.setanyText(content)
     setattr(cls, "setinlineContent", setinlineContent)
     
     def getinlineContent(self):
         if self.inline:
-            return self.inline.gettext()
+            return self.inline.getanyText()
         return None
     setattr(cls, "getinlineContent", getinlineContent)
 
@@ -2571,7 +2569,7 @@
                        criteria, parent_infos)
     setattr(cls, "Search", Search)
 
-cls = _initElementClass("actionBlock", "commonObjects_actionBlock", "single")
+cls = _initElementClass("actionBlock", "commonObjects", "single")
 if cls:
     def compatibility(self, tree):
         for child in tree.childNodes[:]:
@@ -2649,7 +2647,7 @@
 def _SearchInIOVariable(self, criteria, parent_infos=[]):
     return _Search([("expression", self.getexpression())], criteria, parent_infos + ["io_variable", self.getlocalId()])
 
-cls = _initElementClass("inVariable", "fbdObjects_inVariable")
+cls = _initElementClass("inVariable", "fbdObjects")
 if cls:
     setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True))
     
@@ -2664,7 +2662,7 @@
 
     setattr(cls, "Search", _SearchInIOVariable)
 
-cls = _initElementClass("outVariable", "fbdObjects_outVariable", "single")
+cls = _initElementClass("outVariable", "fbdObjects", "single")
 if cls:
     setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False))
     
@@ -2679,7 +2677,7 @@
 
     setattr(cls, "Search", _SearchInIOVariable)
 
-cls = _initElementClass("inOutVariable", "fbdObjects_inOutVariable", "single")
+cls = _initElementClass("inOutVariable", "fbdObjects", "single")
 if cls:
     setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True))
     
@@ -2698,7 +2696,7 @@
 def _SearchInConnector(self, criteria, parent_infos=[]):
     return _Search([("name", self.getname())], criteria, parent_infos + ["connector", self.getlocalId()])
 
-cls = _initElementClass("continuation", "commonObjects_continuation")
+cls = _initElementClass("continuation", "commonObjects")
 if cls:
     setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))
     setattr(cls, "Search", _SearchInConnector)
@@ -2708,7 +2706,7 @@
             self.name = new_name
     setattr(cls, "updateElementName", updateElementName)
 
-cls = _initElementClass("connector", "commonObjects_connector", "single")
+cls = _initElementClass("connector", "commonObjects", "single")
 if cls:
     setattr(cls, "getinfos", _getconnectorinfosFunction("connector"))
     setattr(cls, "Search", _SearchInConnector)
@@ -2746,10 +2744,9 @@
     setattr(cls, "setrelPositionXY", setrelPositionXY)
 
     def getrelPositionXY(self):
-        if self.relPosition:
+        if self.relPosition is not None:
             return self.relPosition.getx(), self.relPosition.gety()
-        else:
-            return self.relPosition
+        return self.relPosition
     setattr(cls, "getrelPositionXY", getrelPositionXY)
 
     def addconnection(self):
@@ -2766,7 +2763,7 @@
     setattr(cls, "removeconnections", removeconnections)
     
     def getconnections(self):
-        return self.content
+        return self.xpath("ppx:connection", namespaces=PLCOpenParser.NSMAP)
     setattr(cls, "getconnections", getconnections)
     
     def setconnectionId(self, idx, local_id):
@@ -2811,7 +2808,7 @@
     setattr(cls, "setrelPositionXY", setrelPositionXY)
 
     def getrelPositionXY(self):
-        if self.relPosition:
+        if self.relPosition is not None:
             return self.relPosition.getx(), self.relPosition.gety()
         return self.relPosition
     setattr(cls, "getrelPositionXY", getrelPositionXY)
@@ -2821,12 +2818,13 @@
     def setvalue(self, value):
         value = value.strip()
         if value.startswith("[") and value.endswith("]"):
-            self.content = PLCOpenParser.CreateElement("arrayValue", "value")
+            content = PLCOpenParser.CreateElement("arrayValue", "value")
         elif value.startswith("(") and value.endswith(")"):
-            self.content = PLCOpenParser.CreateElement("structValue", "value")
+            content = PLCOpenParser.CreateElement("structValue", "value")
         else:
-            self.content = PLCOpenParser.CreateElement("simpleValue", "value")
-        self.content.setvalue(value)
+            content = PLCOpenParser.CreateElement("simpleValue", "value")
+        content.setvalue(value)
+        self.setcontent(content)
     setattr(cls, "setvalue", setvalue)
     
     def getvalue(self):
--- a/xmlclass/xmlclass.py	Mon Aug 26 10:55:03 2013 +0200
+++ b/xmlclass/xmlclass.py	Wed Aug 28 11:52:46 2013 +0200
@@ -535,28 +535,33 @@
     return GetModelNameList
 
 def GenerateAnyInfos(infos):
+    
     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")
+        if infos["namespace"][0] == "##any":
+            return tree.xpath("p/text()")[0]
+        return tree.xpath("ns:p/text()", namespaces={"ns": infos["namespace"][0]})[0]
+    
+    def GenerateAny(tree, value):
+        if infos["namespace"][0] == "##any":
+            p = tree.xpath("p")[0]
+        else:
+            p = tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0]
+        p.text = etree.CDATA(value)
+        
+    def InitialAny():
+        text = etree.CDATA(value)
+        if infos["namespace"][0] == "##any":
+            element_name = "p"
+        else:
+            element_name = "{%s}p" % infos["namespace"][0]
+        return etree.Element(element_name, text)
         
     return {
         "type": COMPLEXTYPE, 
         "extract": ExtractAny,
         "generate": GenerateAny,
-        "initial": lambda: "",
-        "check": lambda x: isinstance(x, (StringType, UnicodeType, minidom.Node))
+        "initial": lambda: GenerateAny(""),
+        "check": lambda x: isinstance(x, (StringType, UnicodeType, etree.ElementBase))
     }
 
 def GenerateTagInfos(infos):
@@ -657,6 +662,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:
@@ -1084,8 +1090,9 @@
         pass
     
     def AddEquivalentClass(self, name, base):
-        equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % name, {})
-        equivalences[self.etreeNamespaceFormat % base] = True
+        if name != base:
+            equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {})
+            equivalences[self.etreeNamespaceFormat % name] = True
         
     def AddToLookupClass(self, name, parent, typeinfos):
         lookup_name = self.etreeNamespaceFormat % name
@@ -1129,7 +1136,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
     """
@@ -1166,6 +1178,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):
@@ -1243,13 +1270,14 @@
                     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:
@@ -1266,7 +1294,7 @@
             classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
             classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
             
-        classmembers["_init"] = generateInitMethod(self, classinfos)
+        classmembers["init"] = generateInitMethod(self, classinfos)
         classmembers["getStructure"] = generateStructureMethod(classinfos)
         classmembers["loadXMLTree"] = generateLoadXMLTree(self, classinfos)
         classmembers["generateXMLText"] = generateGenerateXMLText(self, classinfos)
@@ -1366,13 +1394,15 @@
         elif elements.has_key(name):
             element_infos = elements[name]
             element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
-            if name == "content":
+            if element_infos["type"] == CHOICE:
                 content = self.xpath(element_infos["elmt_type"]["choices_xpath"](), namespaces=factory.NSMAP)
                 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)
             else:
                 element_name = factory.etreeNamespaceFormat % name
                 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1:
@@ -1403,7 +1433,7 @@
             if optional_attributes.get(name, False):
                 default = attribute_infos.get("default", None)
                 if value is None or value == default:
-                    self.attrib.pop(name)
+                    self.attrib.pop(name, None)
                     return
             elif attribute_infos.has_key("fixed"):
                 return
@@ -1412,27 +1442,31 @@
         elif elements.has_key(name):
             element_infos = elements[name]
             element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
-            element_xpath = ("%s:%s" % (factory.TargetNamespace, name)
-                             if name != "content"
-                             else elements["content"]["elmt_type"]["choices_xpath"]())
+            if element_infos["type"] == ANY:
+                element_infos["elmt_type"]["generate"](self, value)
             
-            for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
-                self.remove(element)
-            
-            if value is not None:
-                previous_elements_xpath = "|".join(map(
-                    lambda x: "%s:%s" % (factory.TargetNamespace, x)
-                              if x != "content"
-                              else elements["content"]["elmt_type"]["choices_xpath"](),
-                    elements.keys()[elements.keys().index(name)]))
+            else:
+                element_xpath = ("%s:%s" % (factory.TargetNamespace, name)
+                                 if name != "content"
+                                 else elements["content"]["elmt_type"]["choices_xpath"]())
                 
-                insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
+                for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
+                    self.remove(element)
                 
-                if not isinstance(value, ListType):
-                    value = [value]
+                if value is not None:
+                    previous_elements_xpath = "|".join(map(
+                        lambda x: "%s:%s" % (factory.TargetNamespace, x)
+                                  if x != "content"
+                                  else elements["content"]["elmt_type"]["choices_xpath"](),
+                        elements.keys()[elements.keys().index(name)]))
                     
-                for element in reversed(value):
-                    self.insert(insertion_point, element)
+                    insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
+                    
+                    if not isinstance(value, ListType):
+                        value = [value]
+                        
+                    for element in reversed(value):
+                        self.insert(insertion_point, element)
         
         elif classinfos.has_key("base"):
             return classinfos["base"].__setattr__(self, name, value)
@@ -1827,21 +1861,23 @@
     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" and self.get(attribute["name"]) is None:
+            if attribute["use"] == "required":
                 self.set(attribute["name"], attribute["attr_type"]["generate"](attribute["attr_type"]["initial"]()))
         for element in classinfos["elements"]:
-            if element["name"] != "content":
+            if element["type"] != CHOICE:
                 element_name = (
                     etree.QName(factory.NSMAP["xhtml"], "p")
                     if element["type"] == ANY
                     else factory.etreeNamespaceFormat % element["name"])
-                if self.find(element_name) is None:
-                    initial = GetElementInitialValue(factory, element)
-                    if initial is not None:
-                        map(self.append, initial)
+                initial = GetElementInitialValue(factory, element)
+                if initial is not None:
+                    for value in initial:
+                        DefaultElementClass.__setattr__(value, "tag", element_name)
+                        value.init()
+                        self.append(value)
     return initMethod
 
 def generateSetMethod(attr):
@@ -1966,7 +2002,9 @@
 """
 
 class DefaultElementClass(etree.ElementBase):
-    toto = True
+    
+    def init(self):
+        pass
     
     def getLocalTag(self):
         return etree.QName(self.tag).localname
@@ -1976,10 +2014,9 @@
 
 class XMLElementClassLookUp(etree.PythonElementClassLookup):
     
-    def __init__(self, classes, class_equivalence, *args, **kwargs):
+    def __init__(self, classes, *args, **kwargs):
         etree.PythonElementClassLookup.__init__(self, *args, **kwargs)
         self.LookUpClasses = classes
-        self.ClassEquivalence = class_equivalence
     
     def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass):
         element_class = self.LookUpClasses.get(element_tag, (default, None))
@@ -1991,9 +2028,6 @@
         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)
-        elif element_with_parent_class == DefaultElementClass:
-            for equivalent_parent in self.ClassEquivalence.get(parent_tag, {}).keys():
-                return self.GetElementClass(element_tag, equivalent_parent, default)
         return element_with_parent_class
         
     def lookup(self, document, element):
@@ -2022,9 +2056,11 @@
     
     def CreateRoot(self):
         if self.BaseClass is not None:
-            return self.makeelement(
+            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):
@@ -2037,6 +2073,7 @@
     def CreateElement(self, element_tag, parent_tag=None):
         new_element = self.GetElementClass(element_tag, parent_tag)()
         DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
+        new_element.init()
         return new_element
     
 def GenerateParser(factory, xsdstring):
@@ -2054,8 +2091,9 @@
         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, factory.EquivalentClassesParent)
+    class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp)
     parser.set_element_class_lookup(class_lookup)
+    
     return parser
 
 def UpdateXMLClassGlobals(classes):