# HG changeset patch # User Laurent Bessard # Date 1377683566 -7200 # Node ID 42ea51d083ce7ab7066ff086c2dc94a9f5baec47 # Parent 13ee5f4ab6127c997e90e30ec8d5fe581c913746 Second stage of xmlclass refactoring using lxml , project are loaded and displayed successfully diff -r 13ee5f4ab612 -r 42ea51d083ce PLCControler.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) diff -r 13ee5f4ab612 -r 42ea51d083ce plcopen/plcopen.py --- 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): diff -r 13ee5f4ab612 -r 42ea51d083ce xmlclass/xmlclass.py --- 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'\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):