--- a/PLCControler.py Mon Sep 23 00:32:39 2013 +0200
+++ b/PLCControler.py Tue Sep 24 00:44:06 2013 +0200
@@ -1377,8 +1377,8 @@
return_type_infos_xslt_tree = etree.XSLT(
variables_infos_xslt, extensions = {
("var_infos_ns", "var_tree"): VarTree(self)})
- return [extract_param(el)
- for el in return_type_infos_xslt_tree(return_type).getroot()]
+ return [extract_param(el) + for el in return_type_infos_xslt_tree(return_type).getroot()] @@ -2486,9 +2486,7 @@
for param, value in infos.items():
- expression = PLCOpenParser.CreateElement("expression", variable.getLocalTag())
- expression.text = value
- variable.setexpression(expression)
+ variable.setexpression(value) elif param == "executionOrder" and variable.getexecutionOrderId() != value:
element.setelementExecutionOrder(variable, value)
@@ -2639,9 +2637,7 @@
for param, value in infos.items():
- variable = PLCOpenParser.CreateElement("variable", "contact")
- contact.setvariable(variable)
+ contact.setvariable(value) CONTACT_NORMAL: (False, "none"),
@@ -2684,9 +2680,7 @@
for param, value in infos.items():
- variable = PLCOpenParser.CreateElement("variable", "coil")
- coil.setvariable(variable)
+ coil.setvariable(value) negated, storage, edge = {
COIL_NORMAL: (False, "none", "none"),
--- a/PLCGenerator.py Mon Sep 23 00:32:39 2013 +0200
+++ b/PLCGenerator.py Tue Sep 24 00:44:06 2013 +0200
@@ -701,7 +701,7 @@
for instance in body.getcontentInstances():
if isinstance(instance, (InVariableClass, OutVariableClass,
- expression = instance.getexpression().text
+ expression = instance.getexpression() var_type = self.GetVariableType(expression)
if (isinstance(pou, TransitionObjClass)
and expression == pou.getname()):
@@ -933,7 +933,7 @@
expression = self.ComputeExpression(body, connections)
if expression is not None:
self.Program += [(self.CurrentIndent, ()),
- (instance.getexpression().text, (self.TagName, "io_variable", instance.getlocalId(), "expression")),
+ (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), self.Program += expression
self.Program += [(";\n", ())]
@@ -964,7 +964,7 @@
if expression is not None:
expression = self.ExtractModifier(instance, expression, coil_info)
self.Program += [(self.CurrentIndent, ())]
- self.Program += [(instance.getvariable().text, coil_info + ("reference",))]
+ self.Program += [(instance.getvariable(), coil_info + ("reference",))] self.Program += [(" := ", ())] + expression + [(";\n", ())]
def FactorizePaths(self, paths):
@@ -1187,7 +1187,7 @@
if isinstance(next, LeftPowerRailClass):
elif isinstance(next, (InVariableClass, InOutVariableClass)):
- paths.append(str([(next.getexpression().text, (self.TagName, "io_variable", localId, "expression"))]))
+ paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))])) elif isinstance(next, BlockClass):
block_type = next.gettypeName()
self.ParentGenerator.GeneratePouProgram(block_type)
@@ -1223,7 +1223,7 @@
raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name)
elif isinstance(next, ContactClass):
contact_info = (self.TagName, "contact", next.getlocalId())
- variable = str(self.ExtractModifier(next, [(next.getvariable().text, contact_info + ("reference",))], contact_info))
+ variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) result = self.GeneratePaths(next.connectionPointIn.getconnections(), body, order)
factorized_paths = self.FactorizePaths(result)
@@ -1482,8 +1482,8 @@
(ReIndentText(transitionBody.getanyText(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))]
for instance in transitionBody.getcontentInstances():
- if isinstance(instance, OutVariableClass) and instance.getexpression().text == transitionValues["value"]\
- or isinstance(instance, CoilClass) and instance.getvariable().text == transitionValues["value"]:
+ if isinstance(instance, OutVariableClass) and instance.getexpression() == transitionValues["value"]\ + or isinstance(instance, CoilClass) and instance.getvariable() == transitionValues["value"]: connections = instance.connectionPointIn.getconnections()
if connections is not None:
expression = self.ComputeExpression(transitionBody, connections)
--- a/plcopen/plcopen.py Mon Sep 23 00:32:39 2013 +0200
+++ b/plcopen/plcopen.py Tue Sep 24 00:44:06 2013 +0200
@@ -220,7 +220,7 @@
new_address = groups[0] + new_leading + groups[2]
text = text[:result.start()] + new_address + text[result.end():]
startpos = result.start() + len(new_address)
- result = address_model.search(self.text, startpos)
+ result = address_model.search(text, startpos) setattr(cls, "updateElementAddress", updateElementAddress)
@@ -1876,7 +1876,7 @@
infos = _getelementinfos(self)
specific_values = infos["specific_values"]
- specific_values["name"] = self.getexpression().text
+ specific_values["name"] = self.getexpression() _getexecutionOrder(self, specific_values)
infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input"))
@@ -1920,7 +1920,7 @@
infos = _getelementinfos(self)
infos["type"] = ld_element_type
specific_values = infos["specific_values"]
- specific_values["name"] = self.getvariable().text
+ specific_values["name"] = self.getvariable() _getexecutionOrder(self, specific_values)
specific_values["negated"] = self.getnegated()
specific_values["edge"] = self.getedge()
@@ -2050,15 +2050,15 @@
setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail"))
def _UpdateLDElementName(self, old_name, new_name):
- if self.variable.text == old_name:
- self.variable.text = new_name
+ if self.variable == old_name: + self.variable = new_name def _UpdateLDElementAddress(self, address_model, new_leading):
- self.variable.text = update_address(self.variable.text, address_model, new_leading)
+ self.variable = update_address(self.variable, address_model, new_leading) def _getSearchInLDElement(ld_element_type):
def SearchInLDElement(self, criteria, parent_infos=[]):
- return _Search([("reference", self.variable.text)], criteria, parent_infos + [ld_element_type, self.getlocalId()])
+ return _Search([("reference", self.variable)], criteria, parent_infos + [ld_element_type, self.getlocalId()]) cls = _initElementClass("contact", "ldObjects", "single")
@@ -2412,14 +2412,14 @@
setattr(cls, "Search", Search)
def _SearchInIOVariable(self, criteria, parent_infos=[]):
- return _Search([("expression", self.expression.text)], criteria, parent_infos + ["io_variable", self.getlocalId()])
+ return _Search([("expression", self.expression)], criteria, parent_infos + ["io_variable", self.getlocalId()]) def _UpdateIOElementName(self, old_name, new_name):
- if self.expression.text == old_name:
- self.expression.text = new_name
+ if self.expression == old_name: + self.expression = new_name def _UpdateIOElementAddress(self, old_name, new_name):
- self.expression.text = update_address(self.expression.text, address_model, new_leading)
+ self.expression = update_address(self.expression, address_model, new_leading) cls = _initElementClass("inVariable", "fbdObjects")
--- a/xmlclass/xmlclass.py Mon Sep 23 00:32:39 2013 +0200
+++ b/xmlclass/xmlclass.py Tue Sep 24 00:44:06 2013 +0200
@@ -925,7 +925,21 @@
equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {})
equivalences[self.etreeNamespaceFormat % name] = True
+ def AddDistinctionBetweenParentsInLookupClass( + self, lookup_classes, parent, typeinfos): + parent = (self.etreeNamespaceFormat % parent + if parent is not None else None) + parent_class = lookup_classes.get(parent) + if parent_class is not None: + if isinstance(parent_class, ListType): + if typeinfos not in parent_class: + lookup_classes[parent].append(typeinfos) + elif parent_class != typeinfos: + lookup_classes[parent] = [parent_class, typeinfos] + lookup_classes[parent] = typeinfos def AddToLookupClass(self, name, parent, typeinfos):
lookup_name = self.etreeNamespaceFormat % name
if isinstance(typeinfos, (StringType, UnicodeType)):
@@ -935,13 +949,14 @@
if lookup_classes is None:
self.ComputedClassesLookUp[lookup_name] = (typeinfos, parent)
elif isinstance(lookup_classes, DictType):
- lookup_classes[self.etreeNamespaceFormat % parent
- if parent is not None else None] = typeinfos
+ self.AddDistinctionBetweenParentsInLookupClass( + lookup_classes, parent, typeinfos) - lookup_classes = {self.etreeNamespaceFormat % lookup_classes[1]
- if lookup_classes[1] is not None else None: lookup_classes[0]}
- lookup_classes[self.etreeNamespaceFormat % parent
- if parent is not None else None] = typeinfos
+ self.etreeNamespaceFormat % lookup_classes[1] + if lookup_classes[1] is not None else None: lookup_classes[0]} + self.AddDistinctionBetweenParentsInLookupClass( + lookup_classes, parent, typeinfos) self.ComputedClassesLookUp[lookup_name] = lookup_classes
def ExtractTypeInfos(self, name, parent, typeinfos):
@@ -1130,6 +1145,7 @@
classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
classmembers["_init_"] = generateInitMethod(self, classinfos)
+ classmembers["StructurePattern"] = GetStructurePattern(classinfos) classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
@@ -1177,6 +1193,60 @@
+Method that generate the method for generating the xml tree structure model by +following the attributes list defined +def ComputeMultiplicity(name, infos): + if infos["minOccurs"] == 0: + if infos["maxOccurs"] == "unbounded": + return "(?:%s)*" % name + elif infos["maxOccurs"] == 1: + return "(?:%s)?" % name + return "(?:%s){,%d}" % (name, infos["maxOccurs"]) + elif infos["minOccurs"] == 1: + if infos["maxOccurs"] == "unbounded": + return "(?:%s)+" % name + elif infos["maxOccurs"] == 1: + return "(?:%s){1,%d}" % (name, infos["maxOccurs"]) + if infos["maxOccurs"] == "unbounded": + return "(?:%s){%d,}" % (name, infos["minOccurs"], name) + return "(?:%s){%d,%d}" % (name, infos["minOccurs"], +def GetStructurePattern(classinfos): + base_structure_pattern = ( + classinfos["base"].StructurePattern.pattern[:-1] + if classinfos.has_key("base") else "") + for element in classinfos["elements"]: + if element["type"] == ANY: + elements.append(ComputeMultiplicity("#text |#cdata-section |\w* ", infos)) + elif element["type"] == CHOICE: + for infos in element["choices"]: + if infos["type"] == "sequence": + structure = "(?:%s)" % GetStructurePattern(infos) + structure = "%s " % infos["name"] + choices.append(ComputeMultiplicity(structure, infos)) + elements.append(ComputeMultiplicity("|".join(choices), element)) + elif element["name"] == "content" and element["elmt_type"]["type"] == SIMPLETYPE: + elements.append("(?:#text |#cdata-section )?") + elements.append(ComputeMultiplicity("%s " % element["name"], element)) + if classinfos.get("order", True) or len(elements) == 0: + return re.compile(base_structure_pattern + "".join(elements) + "$") + raise ValueError("XSD structure not yet supported!") Method that generate the method for creating a class instance
def generateClassCreateFunction(class_definition):
@@ -1214,12 +1284,22 @@
elif element_infos["type"] == ANY:
return element_infos["elmt_type"]["extract"](self)
+ elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: + return element_infos["elmt_type"]["extract"](self.text, extract=False) element_name = factory.etreeNamespaceFormat % name
if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1:
- return self.findall(element_name)
+ values = self.findall(element_name) + if element_infos["elmt_type"]["type"] == SIMPLETYPE: + return map(lambda value: + element_infos["elmt_type"]["extract"](value.text, extract=False), - return self.find(element_name)
+ value = self.find(element_name) + if element_infos["elmt_type"]["type"] == SIMPLETYPE: + return element_infos["elmt_type"]["extract"](value.text, extract=False) elif classinfos.has_key("base"):
return classinfos["base"].__getattr__(self, name)
@@ -1252,6 +1332,9 @@
if element_infos["type"] == ANY:
element_infos["elmt_type"]["generate"](self, value)
+ elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: + self.text = element_infos["elmt_type"]["generate"](value) prefix = ("%s:" % factory.TargetNamespace
if factory.TargetNamespace is not None else "")
@@ -1277,8 +1360,12 @@
if not isinstance(value, ListType):
for element in reversed(value):
+ if element_infos["elmt_type"]["type"] == SIMPLETYPE: + tmp_element = etree.Element(factory.etreeNamespaceFormat % name) + tmp_element.text = element_infos["elmt_type"]["generate"](element) self.insert(insertion_point, element)
elif classinfos.has_key("base"):
@@ -1596,6 +1683,8 @@
class DefaultElementClass(etree.ElementBase):
+ StructurePattern = re.compile("$") @@ -1625,8 +1714,19 @@
def lookup(self, document, element):
parent = element.getparent()
- return self.GetElementClass(element.tag,
+ element_class = self.GetElementClass(element.tag, parent.tag if parent is not None else None)
+ if isinstance(element_class, ListType): + "%s " % etree.QName(child.tag).localname + for possible_class in element_class: + if isinstance(possible_class, (StringType, UnicodeType)): + possible_class = self.GetElementClass(possible_class) + if possible_class.StructurePattern.match(children) is not None: + return element_class[0] class XMLClassParser(etree.XMLParser):
@@ -1669,19 +1769,26 @@
if parent_tag is not None else parent_tag,
- def CreateElement(self, element_tag, parent_tag=None):
- new_element = self.GetElementClass(element_tag, parent_tag)()
+ def CreateElement(self, element_tag, parent_tag=None, class_idx=None): + element_class = self.GetElementClass(element_tag, parent_tag) + if isinstance(element_class, ListType): + if class_idx is not None and class_idx < len(element_class): + new_element = element_class[class_idx]() + raise ValueError, "No corresponding class found!" + new_element = element_class() DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
def GenerateParser(factory, xsdstring):
ComputedClasses = factory.CreateClasses()
- if factory.FileName is not None and len(ComputedClasses) == 1:
+ if factory.FileName is not None: ComputedClasses = ComputedClasses[factory.FileName]
BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
- UpdateXMLClassGlobals(ComputedClasses)
factory.etreeNamespaceFormat,
@@ -1693,6 +1800,3 @@
-def UpdateXMLClassGlobals(classes):
- globals().update(classes)
--- a/xmlclass/xsdschema.py Mon Sep 23 00:32:39 2013 +0200
+++ b/xmlclass/xsdschema.py Tue Sep 24 00:44:06 2013 +0200
@@ -924,6 +924,8 @@
factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace]
factory.ComputedClasses.update(include_factory.ComputedClasses)
+ factory.ComputedClassesLookUp.update(include_factory.ComputedClassesLookUp) + factory.EquivalentClassesParent.update(include_factory.EquivalentClassesParent) def ReduceRedefine(factory, attributes, elements):
@@ -1092,7 +1094,11 @@
xsdfile = open(filepath, 'r')
xsdstring = xsdfile.read()
- return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring), filepath), xsdstring)
+ os.chdir(os.path.dirname(filepath)) + parser = GenerateParser(XSDClassFactory(minidom.parseString(xsdstring), filepath), xsdstring) This function generate a xml from the xsd given as a string