Replaced old graphic viewer blocks loading process by xslt stylesheet
authorLaurent Bessard
Wed, 02 Oct 2013 01:21:35 +0200
changeset 1338 c1e6c712cc35
parent 1337 204ef2daa33c
child 1339 6adf05c4508d
Replaced old graphic viewer blocks loading process by xslt stylesheet
PLCControler.py
editors/Viewer.py
graphics/SFC_Objects.py
plcopen/plcopen.py
plcopen/pou_block_instances.xslt
plcopen/pou_block_instances.ysl2
--- a/PLCControler.py	Tue Oct 01 09:24:02 2013 +0200
+++ b/PLCControler.py	Wed Oct 02 01:21:35 2013 +0200
@@ -29,6 +29,7 @@
 import os,sys,re
 import datetime
 from time import localtime
+from collections import OrderedDict, namedtuple
 
 from plcopen import *
 from graphics.GraphicCommons import *
@@ -308,7 +309,6 @@
         self.process_children(context, tagname_infos)
         tagname = etree.Element('tagname')
         tagname.text = self.GetTagName(tagname_infos)
-        print etree.tostring(tagname)
         try:
             output_parent.append(tagname)
         except:
@@ -346,6 +346,158 @@
     os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"))
 
 #-------------------------------------------------------------------------------
+#           Helpers object for generating pou block instances list
+#-------------------------------------------------------------------------------
+
+_BoolValue = lambda x: x in ["true", "0"]
+
+_Point = namedtuple("Point", ["x", "y"])
+
+_BlockInstanceInfos = namedtuple("BlockInstanceInfos", 
+    ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
+
+_BlockSpecificValues = (
+    namedtuple("BlockSpecificValues", 
+               ["name", "execution_order"]),
+    [str, int])
+_VariableSpecificValues = (
+    namedtuple("VariableSpecificValues", 
+               ["name", "value_type", "execution_order"]),
+    [str, str, int])
+_ConnectionSpecificValues = (
+    namedtuple("ConnectionSpecificValues", ["name"]),
+    [str])
+
+_PowerRailSpecificValues = (
+    namedtuple("PowerRailSpecificValues", ["connectors"]),
+    [int])
+
+_LDElementSpecificValues = (
+    namedtuple("LDElementSpecificValues", 
+               ["name", "negated", "edge", "storage", "execution_order"]),
+    [str, _BoolValue, str, str, int])
+
+_DivergenceSpecificValues = (
+    namedtuple("DivergenceSpecificValues", ["connectors"]),
+    [int])
+
+_SpecificValuesTuples = {
+    "comment": (
+        namedtuple("CommentSpecificValues", ["content"]),
+        [str]),
+    "input": _VariableSpecificValues,
+    "output": _VariableSpecificValues,
+    "inout": _VariableSpecificValues,
+    "connector": _ConnectionSpecificValues,
+    "continuation": _ConnectionSpecificValues,
+    "leftPowerRail": _PowerRailSpecificValues,
+    "rightPowerRail": _PowerRailSpecificValues,
+    "contact": _LDElementSpecificValues,
+    "coil": _LDElementSpecificValues,
+    "step": (
+        namedtuple("StepSpecificValues", ["name", "initial", "action"]),
+        [str, _BoolValue, lambda x: x]),
+    "transition": (
+        namedtuple("TransitionSpecificValues", 
+                   ["priority", "condition_type", "condition", "connection"]),
+        [int, str, str, lambda x: x]),
+    "selectionDivergence": _DivergenceSpecificValues,
+    "selectionConvergence": _DivergenceSpecificValues,
+    "simultaneousDivergence": _DivergenceSpecificValues,
+    "simultaneousConvergence": _DivergenceSpecificValues,
+    "jump": (
+        namedtuple("JumpSpecificValues", ["target"]),
+        [str]),
+    "actionBlock": (
+        namedtuple("ActionBlockSpecificValues", ["actions"]),
+        [lambda x: x]),
+}
+
+_InstanceConnectionInfos = namedtuple("InstanceConnectionInfos",
+    ["name", "negated", "edge", "position", "links"])
+
+_ConnectionLinkInfos = namedtuple("ConnectionLinkInfos",
+    ["refLocalId", "formalParameter", "points"])
+
+_ActionInfos = namedtuple("ActionInfos",
+    ["qualifier", "type", "value", "duration", "indicator"])
+
+def _translate_args(translations, args):
+    return [translate(arg[0]) if len(arg) > 0 else None 
+            for translate, arg in
+            zip(translations, args)]
+
+class BlockInstanceFactory:
+    
+    def __init__(self, block_instances):
+        self.BlockInstances = block_instances
+        self.CurrentInstance = None
+        self.SpecificValues = None
+        self.CurrentConnection = None
+        self.CurrentLink = None
+    
+    def SetSpecificValues(self, context, *args):
+        self.SpecificValues = list(args)
+        self.CurrentInstance = None
+        self.CurrentConnection = None
+        self.CurrentLink = None
+    
+    def AddBlockInstance(self, context, *args):
+        specific_values_tuple, specific_values_translation = \
+            _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
+        
+        if (args[0][0] == "step" and len(self.SpecificValues) < 3 or
+            args[0][0] == "transition" and len(self.SpecificValues) < 4):
+            self.SpecificValues.append([None])
+        elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
+            self.SpecificValues.append([[]])
+        specific_values = specific_values_tuple(*_translate_args(
+            specific_values_translation, self.SpecificValues))
+        self.SpecificValues = None
+        
+        self.CurrentInstance = _BlockInstanceInfos(
+            *(_translate_args([str] + [int] * 5, args) + 
+              [specific_values, [], []]))
+        
+        self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
+        
+    def AddInstanceConnection(self, context, *args):
+        connection_args = _translate_args(
+            [str, str, _BoolValue, str, int, int], args)
+        
+        self.CurrentConnection = _InstanceConnectionInfos(
+            *(connection_args[1:4] + [
+                _Point(*connection_args[4:6]), []]))
+        
+        if self.CurrentInstance is not None:
+            if connection_args[0] == "input":
+                self.CurrentInstance.inputs.append(self.CurrentConnection)
+            else:
+                self.CurrentInstance.outputs.append(self.CurrentConnection)
+        else:
+            self.SpecificValues.append([self.CurrentConnection])
+    
+    def AddConnectionLink(self, context, *args):
+        self.CurrentLink = _ConnectionLinkInfos(
+            *(_translate_args([int, str], args) + [[]]))
+        self.CurrentConnection.links.append(self.CurrentLink)
+    
+    def AddLinkPoint(self, context, *args):
+        self.CurrentLink.points.append(_Point(
+            *_translate_args([int, int], args)))
+    
+    def AddAction(self, context, *args):
+        if len(self.SpecificValues) == 0:
+            self.SpecificValues.append([[]])
+        translated_args = _translate_args([str] * 5, args)
+        if translated_args[0] is None:
+            translated_args[0] = ""
+        self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
+    
+pou_block_instances_xslt = etree.parse(
+    os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
+
+#-------------------------------------------------------------------------------
 #                         Undo Buffer for PLCOpenEditor
 #-------------------------------------------------------------------------------
 
@@ -636,7 +788,6 @@
         return None
 
     def GetPouVariables(self, tagname, debug = False):
-        vars = []
         pou_type = None
         project = self.GetProject(debug)
         if project is not None:
@@ -1616,8 +1767,8 @@
             basetype_type = basetype.getLocalTag()
             return (basetype.getname() if basetype_type == "derived"
                     else basetype_type.upper())
-        elif basetype_content_type == "derived":
-            return basetype_content_type.getname()
+        return (basetype_content.getname() if basetype_content_type == "derived"
+                else basetype_content_type.upper())
         return None
 
     # Return Base Type of given possible derived type
@@ -2289,25 +2440,22 @@
             
             return new_id, connections
     
-    # Return the current pou editing instances idx
-    def GetEditedElementInstancesIds(self, tagname, debug = False):
+    def GetEditedElementInstancesInfos(self, tagname, debug = False):
+        element_instances = OrderedDict()
         element = self.GetEditedElement(tagname, debug)
         if element is not None:
-            return element.getinstancesIds()
-        return []
-    
-    # Return the current pou editing informations
-    def GetEditedElementInstanceInfos(self, tagname, id, debug = False):
-        element = self.GetEditedElement(tagname, debug)
-        if element is not None:
-            instance = element.getinstance(id)
-            if instance is not None:
-                infos = instance.getinfos()
-                if infos["type"] in ["input", "output", "inout"]:
-                    var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug)
-                    infos["specific_values"]["value_type"] = var_type
-                return infos
-        return None
+            factory = BlockInstanceFactory(element_instances)
+            
+            pou_block_instances_xslt_tree = etree.XSLT(
+                pou_block_instances_xslt, 
+                extensions = {
+                    ("pou_block_instances_ns", name): getattr(factory, name)
+                    for name in ["AddBlockInstance", "SetSpecificValues",
+                                 "AddInstanceConnection", "AddConnectionLink",
+                                 "AddLinkPoint", "AddAction"]})
+        
+            pou_block_instances_xslt_tree(element)
+        return element_instances
     
     def ClearEditedElementExecutionOrder(self, tagname):
         element = self.GetEditedElement(tagname)
@@ -2319,29 +2467,6 @@
         if element is not None:
             element.compileexecutionOrder()
     
-    # Return the variable type of the given pou
-    def GetEditedElementVarValueType(self, tagname, varname, debug = False):
-        project = self.GetProject(debug)
-        if project is not None:
-            words = tagname.split("::")
-            if words[0] in ["P","T","A"]:
-                pou = self.Project.getpou(words[1])
-                if pou is not None:
-                    if words[0] == "T" and varname == words[2]:
-                        return "BOOL"
-                    if words[1] == varname:
-                        return self.GetPouInterfaceReturnType(pou)[0]
-                    for type, varlist in pou.getvars():
-                        for var in varlist.getvariable():
-                            if var.getname() == varname:
-                                vartype_content = var.gettype().getcontent()
-                                vartype_content_type = vartype_content.getLocalTag()
-                                if vartype_content_type == "derived":
-                                    return vartype_content.getname()
-                                else:
-                                    return vartype_content_type.upper()
-        return None
-    
     def SetConnectionWires(self, connection, connector):
         wires = connector.GetWires()
         idx = 0
--- a/editors/Viewer.py	Tue Oct 01 09:24:02 2013 +0200
+++ b/editors/Viewer.py	Wed Oct 02 01:21:35 2013 +0200
@@ -84,36 +84,38 @@
 def GetVariableCreationFunction(variable_type):
     def variableCreationFunction(viewer, id, specific_values):
         return FBD_Variable(viewer, variable_type, 
-                                    specific_values["name"], 
-                                    specific_values["value_type"], 
+                                    specific_values.name, 
+                                    specific_values.value_type, 
                                     id,
-                                    specific_values["executionOrder"])
+                                    specific_values.execution_order)
     return variableCreationFunction
 
 def GetConnectorCreationFunction(connector_type):
     def connectorCreationFunction(viewer, id, specific_values):
         return FBD_Connector(viewer, connector_type, 
-                                     specific_values["name"], id)
+                                     specific_values.name, id)
     return connectorCreationFunction
 
 def commentCreationFunction(viewer, id, specific_values):
-    return Comment(viewer, specific_values["content"], id)
+    return Comment(viewer, specific_values.content, id)
 
 def GetPowerRailCreationFunction(powerrail_type):
     def powerRailCreationFunction(viewer, id, specific_values):
         return LD_PowerRail(viewer, powerrail_type, id, 
-                                    specific_values["connectors"])
+                                    specific_values.connectors)
     return powerRailCreationFunction
 
+MODIFIER_VALUE = lambda x: x if x is not None else 'none'
+
 CONTACT_TYPES = {(True, "none"): CONTACT_REVERSE,
                  (False, "rising"): CONTACT_RISING,
                  (False, "falling"): CONTACT_FALLING}
 
 def contactCreationFunction(viewer, id, specific_values):
-    contact_type = CONTACT_TYPES.get((specific_values.get("negated", False), 
-                                      specific_values.get("edge", "none")),
+    contact_type = CONTACT_TYPES.get((specific_values.negated, 
+                                      MODIFIER_VALUE(specific_values.edge)),
                                      CONTACT_NORMAL)
-    return LD_Contact(viewer, contact_type, specific_values["name"], id)
+    return LD_Contact(viewer, contact_type, specific_values.name, id)
 
 COIL_TYPES = {(True, "none", "none"): COIL_REVERSE,
               (False, "none", "set"): COIL_SET,
@@ -122,38 +124,38 @@
               (False, "falling", "none"): COIL_FALLING}
 
 def coilCreationFunction(viewer, id, specific_values):
-    coil_type = COIL_TYPES.get((specific_values.get("negated", False), 
-                                specific_values.get("edge", "none"),
-                                specific_values.get("storage", "none")),
+    coil_type = COIL_TYPES.get((specific_values.negated, 
+                                MODIFIER_VALUE(specific_values.edge),
+                                MODIFIER_VALUE(specific_values.storage)),
                                COIL_NORMAL)
-    return LD_Coil(viewer, coil_type, specific_values["name"], id)
+    return LD_Coil(viewer, coil_type, specific_values.name, id)
 
 def stepCreationFunction(viewer, id, specific_values):
-    step = SFC_Step(viewer, specific_values["name"], 
-                            specific_values.get("initial", False), id)
-    if specific_values.get("action", None):
+    step = SFC_Step(viewer, specific_values.name, 
+                            specific_values.initial, id)
+    if specific_values.action is not None:
         step.AddAction()
         connector = step.GetActionConnector()
-        connector.SetPosition(wx.Point(*specific_values["action"]["position"]))
+        connector.SetPosition(wx.Point(*specific_values.action.position))
     return step
 
 def transitionCreationFunction(viewer, id, specific_values):
-    transition = SFC_Transition(viewer, specific_values["condition_type"], 
-                                        specific_values.get("condition", None), 
-                                        specific_values["priority"], id)
+    transition = SFC_Transition(viewer, specific_values.condition_type, 
+                                        specific_values.condition, 
+                                        specific_values.priority, id)
     return transition
 
 def GetDivergenceCreationFunction(divergence_type):
     def divergenceCreationFunction(viewer, id, specific_values):
         return SFC_Divergence(viewer, divergence_type, 
-                                      specific_values["connectors"], id)
+                                      specific_values.connectors, id)
     return divergenceCreationFunction
 
 def jumpCreationFunction(viewer, id, specific_values):
-    return SFC_Jump(viewer, specific_values["target"], id)
+    return SFC_Jump(viewer, specific_values.target, id)
 
 def actionBlockCreationFunction(viewer, id, specific_values):
-    return SFC_ActionBlock(viewer, specific_values["actions"], id)
+    return SFC_ActionBlock(viewer, specific_values.actions, id)
 
 ElementCreationFunctions = {
     "input": GetVariableCreationFunction(INPUT),
@@ -1089,13 +1091,10 @@
         self.ResetBuffer()
         instance = {}
         # List of ids of already loaded blocks
-        ids = self.Controler.GetEditedElementInstancesIds(self.TagName, debug = self.Debug)
+        instances = self.Controler.GetEditedElementInstancesInfos(self.TagName, debug = self.Debug)
         # Load Blocks until they are all loaded
-        while len(ids) > 0:
-            instance = self.Controler.GetEditedElementInstanceInfos(
-                self.TagName, ids.popitem(0)[0], debug = self.Debug)
-            if instance is not None:
-                self.loadInstance(instance, ids, selection)
+        while len(instances) > 0:
+            self.loadInstance(instances.popitem(0)[1], instances, selection)
         
         if (selection is not None and 
             isinstance(self.SelectedElement, Graphic_Group)):
@@ -1221,119 +1220,119 @@
             self.SelectedElement = group
         
     # Load instance from given informations
-    def loadInstance(self, instance, ids, selection):
-        self.current_id = max(self.current_id, instance["id"])
-        creation_function = ElementCreationFunctions.get(instance["type"], None)
+    def loadInstance(self, instance, remaining_instances, selection):
+        self.current_id = max(self.current_id, instance.id)
+        creation_function = ElementCreationFunctions.get(instance.type, None)
         connectors = {"inputs" : [], "outputs" : []}
-        specific_values = instance["specific_values"]
+        specific_values = instance.specific_values
         if creation_function is not None:
-            element = creation_function(self, instance["id"], specific_values)
+            element = creation_function(self, instance.id, specific_values)
             if isinstance(element, SFC_Step):
-                if len(instance["inputs"]) > 0:
+                if len(instance.inputs) > 0:
                     element.AddInput()
                 else:
                     element.RemoveInput()
-                if len(instance["outputs"]) > 0:
+                if len(instance.outputs) > 0:
                     element.AddOutput()
-            if isinstance(element, SFC_Transition) and specific_values["condition_type"] == "connection":
+            if isinstance(element, SFC_Transition) and specific_values.condition_type == "connection":
                 connector = element.GetConditionConnector()
-                self.CreateWires(connector, instance["id"], specific_values["connection"]["links"], ids, selection)
+                self.CreateWires(connector, instance.id, specific_values.connection.links, remaining_instances, selection)
         else:
             executionControl = False
-            for input in instance["inputs"]:
-                if input["negated"]:
-                    connectors["inputs"].append((input["name"], None, "negated"))
-                elif input["edge"]:
-                    connectors["inputs"].append((input["name"], None, input["edge"]))
+            for input in instance.inputs:
+                input_edge = MODIFIER_VALUE(input.edge)
+                if input.negated:
+                    connectors["inputs"].append((input.name, None, "negated"))
+                elif input_edge:
+                    connectors["inputs"].append((input.name, None, input_edge))
                 else:
-                    connectors["inputs"].append((input["name"], None, "none"))
-            for output in instance["outputs"]:
-                if output["negated"]:
-                    connectors["outputs"].append((output["name"], None, "negated"))
-                elif output["edge"]:
-                    connectors["outputs"].append((output["name"], None, output["edge"]))
+                    connectors["inputs"].append((input.name, None, "none"))
+            for output in instance.outputs:
+                output_edge = MODIFIER_VALUE(output.edge)
+                if output.negated:
+                    connectors["outputs"].append((output.name, None, "negated"))
+                elif output_edge:
+                    connectors["outputs"].append((output.name, None, output_edge))
                 else:
-                    connectors["outputs"].append((output["name"], None, "none"))
+                    connectors["outputs"].append((output.name, None, "none"))
             if len(connectors["inputs"]) > 0 and connectors["inputs"][0][0] == "EN":
                 connectors["inputs"].pop(0)
                 executionControl = True
             if len(connectors["outputs"]) > 0 and connectors["outputs"][0][0] == "ENO":
                 connectors["outputs"].pop(0)
                 executionControl = True
-            if specific_values["name"] is None:
-                specific_values["name"] = ""
-            element = FBD_Block(self, instance["type"], specific_values["name"], 
-                      instance["id"], len(connectors["inputs"]), 
+            block_name = specific_values.name if specific_values.name is not None else ""
+            element = FBD_Block(self, instance.type, block_name, 
+                      instance.id, len(connectors["inputs"]), 
                       connectors=connectors, executionControl=executionControl, 
-                      executionOrder=specific_values["executionOrder"])
+                      executionOrder=specific_values.execution_order)
         if isinstance(element, Comment):
             self.AddComment(element)
         else:
             self.AddBlock(element)
             connectors = element.GetConnectors()
-        element.SetPosition(instance["x"], instance["y"])
-        element.SetSize(instance["width"], instance["height"])
-        for i, output_connector in enumerate(instance["outputs"]):
+        element.SetPosition(instance.x, instance.y)
+        element.SetSize(instance.width, instance.height)
+        for i, output_connector in enumerate(instance.outputs):
+            connector_pos = wx.Point(*output_connector.position)
             if isinstance(element, FBD_Block):
-                connector = element.GetConnector(
-                    wx.Point(*output_connector["position"]),
-                    output_name = output_connector["name"])
+                connector = element.GetConnector(connector_pos,
+                    output_name = output_connector.name)
             elif i < len(connectors["outputs"]):
                 connector = connectors["outputs"][i]
             else:
                 connector = None
             if connector is not None:
-                if output_connector.get("negated", False):
+                if output_connector.negated:
                     connector.SetNegated(True)
-                if output_connector.get("edge", "none") != "none":
-                    connector.SetEdge(output_connector["edge"])
+                if output_connector.edge is not None:
+                    connector.SetEdge(output_connector.edge)
                 if connectors["outputs"].index(connector) == i:
-                    connector.SetPosition(wx.Point(*output_connector["position"]))
-        for i, input_connector in enumerate(instance["inputs"]):
+                    connector.SetPosition(connector_pos)
+        for i, input_connector in enumerate(instance.inputs):
+            connector_pos = wx.Point(*input_connector.position)
             if isinstance(element, FBD_Block):
-                connector = element.GetConnector(
-                    wx.Point(*input_connector["position"]),
-                    input_name = input_connector["name"])
+                connector = element.GetConnector(connector_pos,
+                    input_name = input_connector.name)
             elif i < len(connectors["inputs"]):
                 connector = connectors["inputs"][i]
             else:
                 connector = None
             if connector is not None:
                 if connectors["inputs"].index(connector) == i:
-                    connector.SetPosition(wx.Point(*input_connector["position"]))
-                if input_connector.get("negated", False):
+                    connector.SetPosition(connector_pos)
+                if input_connector.negated:
                     connector.SetNegated(True)
-                if input_connector.get("edge", "none") != "none":
-                    connector.SetEdge(input_connector["edge"])
-                if not self.CreateWires(connector, instance["id"], input_connector["links"], ids, selection):
+                if input_connector.edge is not None:
+                    connector.SetEdge(input_connector.edge)
+                if not self.CreateWires(connector, instance.id, input_connector.links, remaining_instances, selection):
                     element.RefreshModel()
         element.RefreshConnectors()
-        if selection is not None and selection[0].get(instance["id"], False):
+        if selection is not None and selection[0].get(instance.id, False):
             self.SelectInGroup(element)
 
-    def CreateWires(self, start_connector, id, links, ids, selection=None):
+    def CreateWires(self, start_connector, id, links, remaining_instances, selection=None):
         links_connected = True
         for link in links:
-            refLocalId = link["refLocalId"]
+            refLocalId = link.refLocalId
             if refLocalId is None:
                 links_connected = False
                 continue
             
-            if ids.pop(refLocalId, False):
-                new_instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, refLocalId, debug = self.Debug)
-                if new_instance is not None:
-                    self.loadInstance(new_instance, ids, selection)
+            new_instance = remaining_instances.pop(refLocalId, None)
+            if new_instance is not None:
+                self.loadInstance(new_instance, remaining_instances, selection)
             
             connected = self.FindElementById(refLocalId)
             if connected is None:
                 links_connected = False
                 continue
             
-            points = link["points"]
+            points = link.points
             end_connector = connected.GetConnector(
-                wx.Point(points[-1][0], points[-1][1])
+                wx.Point(points[-1].x, points[-1].y)
                 if len(points) > 0 else wx.Point(0, 0), 
-                link["formalParameter"])
+                link.formalParameter)
             if end_connector is not None:
                 if len(points) > 0:
                     wire = Wire(self)
--- a/graphics/SFC_Objects.py	Tue Oct 01 09:24:02 2013 +0200
+++ b/graphics/SFC_Objects.py	Wed Oct 02 01:21:35 2013 +0200
@@ -1894,18 +1894,18 @@
         self.ColSize = [0, 0, 0]
         min_height = 0
         for action in self.Actions:
-            width, height = self.Parent.GetTextExtent(action["qualifier"])
+            width, height = self.Parent.GetTextExtent(action.qualifier)
             self.ColSize[0] = max(self.ColSize[0], width + 10)
             row_height = height
-            if action.has_key("duration"):
-                width, height = self.Parent.GetTextExtent(action["duration"])
+            if action.duration is not None:
+                width, height = self.Parent.GetTextExtent(action.duration)
                 row_height = max(row_height, height)
                 self.ColSize[0] = max(self.ColSize[0], width + 10)
-            width, height = self.Parent.GetTextExtent(action["value"])
+            width, height = self.Parent.GetTextExtent(action.value)
             row_height = max(row_height, height)
             self.ColSize[1] = max(self.ColSize[1], width + 10)
-            if action.get("indicator", "") != "":
-                width, height = self.Parent.GetTextExtent(action["indicator"])
+            if action.indicator is not None:
+                width, height = self.Parent.GetTextExtent(action.indicator)
                 row_height = max(row_height, height)
                 self.ColSize[2] = max(self.ColSize[2], width + 10)
             min_height += row_height + 5
@@ -2022,39 +2022,39 @@
             if i != 0:
                 dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size, 
                     self.Pos.x + self.Size[0], self.Pos.y + i * line_size)
-            qualifier_size = dc.GetTextExtent(action["qualifier"])
-            if action.has_key("duration"):
+            qualifier_size = dc.GetTextExtent(action.qualifier)
+            if action.duration is not None:
                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2,
                                  self.Pos.y + i * line_size + line_size / 2 - qualifier_size[1])
-                duration_size = dc.GetTextExtent(action["duration"])
+                duration_size = dc.GetTextExtent(action.duration)
                 duration_pos = (self.Pos.x + (colsize[0] - duration_size[0]) / 2,
                                 self.Pos.y + i * line_size + line_size / 2)
-                dc.DrawText(action["duration"], duration_pos[0], duration_pos[1])
+                dc.DrawText(action.duration, duration_pos[0], duration_pos[1])
             else:
                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2,
                                  self.Pos.y + i * line_size + (line_size - qualifier_size[1]) / 2)
-            dc.DrawText(action["qualifier"], qualifier_pos[0], qualifier_pos[1])
-            content_size = dc.GetTextExtent(action["value"])
+            dc.DrawText(action.qualifier, qualifier_pos[0], qualifier_pos[1])
+            content_size = dc.GetTextExtent(action.value)
             content_pos = (self.Pos.x + colsize[0] + (colsize[1] - content_size[0]) / 2,
                            self.Pos.y + i * line_size + (line_size - content_size[1]) / 2)
-            dc.DrawText(action["value"], content_pos[0], content_pos[1])
-            if action.has_key("indicator"):
-                indicator_size = dc.GetTextExtent(action["indicator"])
+            dc.DrawText(action.value, content_pos[0], content_pos[1])
+            if action.indicator is not None:
+                indicator_size = dc.GetTextExtent(action.indicator)
                 indicator_pos = (self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - indicator_size[0]) / 2,
                                  self.Pos.y + i * line_size + (line_size - indicator_size[1]) / 2)
-                dc.DrawText(action["indicator"], indicator_pos[0], indicator_pos[1])
+                dc.DrawText(action.indicator, indicator_pos[0], indicator_pos[1])
             
             if not getattr(dc, "printing", False):
                 action_highlights = self.Highlights.get(i, {})
                 for name, attribute_highlights in action_highlights.iteritems():
                     if name == "qualifier":
-                        DrawHighlightedText(dc, action["qualifier"], attribute_highlights, qualifier_pos[0], qualifier_pos[1])
+                        DrawHighlightedText(dc, action.qualifier, attribute_highlights, qualifier_pos[0], qualifier_pos[1])
                     elif name == "duration":
-                        DrawHighlightedText(dc, action["duration"], attribute_highlights, duration_pos[0], duration_pos[1])
+                        DrawHighlightedText(dc, action.duration, attribute_highlights, duration_pos[0], duration_pos[1])
                     elif name in ["reference", "inline"]:
-                        DrawHighlightedText(dc, action["value"], attribute_highlights, content_pos[0], content_pos[1])
+                        DrawHighlightedText(dc, action.value, attribute_highlights, content_pos[0], content_pos[1])
                     elif name == "indicator":
-                        DrawHighlightedText(dc, action["indicator"], attribute_highlights, indicator_pos[0], indicator_pos[1])
+                        DrawHighlightedText(dc, action.indicator, attribute_highlights, indicator_pos[0], indicator_pos[1])
         
         # Draw input connector
         self.Input.Draw(dc)
--- a/plcopen/plcopen.py	Tue Oct 01 09:24:02 2013 +0200
+++ b/plcopen/plcopen.py	Wed Oct 02 01:21:35 2013 +0200
@@ -1874,145 +1874,8 @@
         setattr(cls, "Search", _SearchInElement)
     return cls
 
-def _getexecutionOrder(instance, specific_values):
-    executionOrder = instance.getexecutionOrderId()
-    if executionOrder is None:
-        executionOrder = 0
-    specific_values["executionOrder"] = executionOrder
-    
-def _getdefaultmodifiers(instance, infos):
-    infos["negated"] = instance.getnegated()
-    infos["edge"] = instance.getedge()
-
-def _getinputmodifiers(instance, infos):
-    infos["negated"] = instance.getnegatedIn()
-    infos["edge"] = instance.getedgeIn()
-
-def _getoutputmodifiers(instance, infos):
-    infos["negated"] = instance.getnegatedOut()
-    infos["edge"] = instance.getedgeOut()
-
-MODIFIERS_FUNCTIONS = {"default": _getdefaultmodifiers,
-                       "input": _getinputmodifiers,
-                       "output": _getoutputmodifiers}
-
-def _getconnectioninfos(instance, connection, links=False, modifiers=None, parameter=False):
-    infos = {"position": connection.getrelPositionXY()}
-    if parameter:
-        infos["name"] = instance.getformalParameter()
-    MODIFIERS_FUNCTIONS.get(modifiers, lambda x, y: None)(instance, infos)
-    if links:
-        infos["links"] = []
-        connections = connection.getconnections()
-        if connections is not None:
-            for link in connections:
-                dic = {"refLocalId": link.getrefLocalId(),
-                       "points": link.getpoints(),
-                       "formalParameter": link.getformalParameter()}
-                infos["links"].append(dic)
-    return infos
-
-def _getelementinfos(instance):
-    return {"id": instance.getlocalId(),
-            "x": instance.getx(),
-            "y": instance.gety(),
-            "height": instance.getheight(),
-            "width": instance.getwidth(),
-            "specific_values": {},
-            "inputs": [],
-            "outputs": []}
-
-def _getvariableinfosFunction(type, input, output):
-    def getvariableinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = type
-        specific_values = infos["specific_values"]
-        specific_values["name"] = self.getexpression()
-        _getexecutionOrder(self, specific_values)
-        if input and output:
-            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input"))
-            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "output"))
-        elif input:
-            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "default"))
-        elif output:
-            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default"))
-        return infos
-    return getvariableinfos
-
-def _getconnectorinfosFunction(type):
-    def getconnectorinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = type
-        infos["specific_values"]["name"] = self.getname()
-        if type == "connector":
-            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        elif type == "continuation":
-            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
-        return infos
-    return getconnectorinfos
-
-def _getpowerrailinfosFunction(type):
-    def getpowerrailinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = type
-        if type == "rightPowerRail":
-            for connectionPointIn in self.getconnectionPointIn():
-                infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True))
-            infos["specific_values"]["connectors"] = len(infos["inputs"])
-        elif type == "leftPowerRail":
-            for connectionPointOut in self.getconnectionPointOut():
-                infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
-            infos["specific_values"]["connectors"] = len(infos["outputs"])
-        return infos
-    return getpowerrailinfos
-
-def _getldelementinfosFunction(ld_element_type):
-    def getldelementinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = ld_element_type
-        specific_values = infos["specific_values"]
-        specific_values["name"] = self.getvariable()
-        _getexecutionOrder(self, specific_values)
-        specific_values["negated"] = self.getnegated()
-        specific_values["edge"] = self.getedge()
-        if ld_element_type == "coil":
-            specific_values["storage"] = self.getstorage()
-        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
-        return infos
-    return getldelementinfos
-
-DIVERGENCE_TYPES = {(True, True): "simultaneousDivergence",
-                    (True, False): "selectionDivergence",
-                    (False, True): "simultaneousConvergence",
-                    (False, False): "selectionConvergence"}
-
-def _getdivergenceinfosFunction(divergence, simultaneous):
-    def getdivergenceinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = DIVERGENCE_TYPES[(divergence, simultaneous)]
-        if divergence:
-            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-            for connectionPointOut in self.getconnectionPointOut():
-                infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
-            infos["specific_values"]["connectors"] = len(infos["outputs"])
-        else:
-            for connectionPointIn in self.getconnectionPointIn():
-                infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True))
-            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
-            infos["specific_values"]["connectors"] = len(infos["inputs"])
-        return infos
-    return getdivergenceinfos
-
 cls = _initElementClass("comment", "commonObjects")
 if cls:
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = "comment"
-        infos["specific_values"]["content"] = self.getcontentText()
-        return infos
-    setattr(cls, "getinfos", getinfos)
-    
     def setcontentText(self, text):
         self.content.setanyText(text)
     setattr(cls, "setcontentText", setcontentText)
@@ -2042,19 +1905,6 @@
         return bbox
     setattr(cls, "getBoundingBox", getBoundingBox)
 
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = self.gettypeName()
-        specific_values = infos["specific_values"]
-        specific_values["name"] = self.getinstanceName()
-        _getexecutionOrder(self, specific_values)
-        for variable in self.inputVariables.getvariable():
-            infos["inputs"].append(_getconnectioninfos(variable, variable.connectionPointIn, True, "default", True))
-        for variable in self.outputVariables.getvariable():
-            infos["outputs"].append(_getconnectioninfos(variable, variable.connectionPointOut, False, "default", True))
-        return infos
-    setattr(cls, "getinfos", getinfos)
-
     def updateElementName(self, old_name, new_name):
         if self.typeName == old_name:
             self.typeName = new_name
@@ -2092,14 +1942,6 @@
         return search_result
     setattr(cls, "Search", Search)
 
-cls = _initElementClass("leftPowerRail", "ldObjects")
-if cls:
-    setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail"))
-
-cls = _initElementClass("rightPowerRail", "ldObjects", "multiple")
-if cls:
-    setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail"))
-
 def _UpdateLDElementName(self, old_name, new_name):
     if self.variable == old_name:
         self.variable = new_name
@@ -2114,60 +1956,24 @@
 
 cls = _initElementClass("contact", "ldObjects", "single")
 if cls:
-    setattr(cls, "getinfos", _getldelementinfosFunction("contact"))
     setattr(cls, "updateElementName", _UpdateLDElementName)
     setattr(cls, "updateElementAddress", _UpdateLDElementAddress)
     setattr(cls, "Search", _getSearchInLDElement("contact"))
 
 cls = _initElementClass("coil", "ldObjects", "single")
 if cls:
-    setattr(cls, "getinfos", _getldelementinfosFunction("coil"))
     setattr(cls, "updateElementName", _UpdateLDElementName)
     setattr(cls, "updateElementAddress", _UpdateLDElementAddress)
     setattr(cls, "Search", _getSearchInLDElement("coil"))
 
 cls = _initElementClass("step", "sfcObjects", "single")
 if cls:
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = "step"
-        specific_values = infos["specific_values"]
-        specific_values["name"] = self.getname()
-        specific_values["initial"] = self.getinitialStep()
-        if self.connectionPointIn is not None:
-            infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        if self.connectionPointOut is not None:
-            infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
-        if self.connectionPointOutAction is not None:
-            specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction)
-        return infos
-    setattr(cls, "getinfos", getinfos)
-
     def Search(self, criteria, parent_infos=[]):
         return _Search([("name", self.getname())], criteria, parent_infos + ["step", self.getlocalId()])
     setattr(cls, "Search", Search)
 
 cls = _initElementClass("transition", "sfcObjects")
 if cls:
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = "transition"
-        specific_values = infos["specific_values"]
-        priority = self.getpriority()
-        if priority is None:
-            priority = 0
-        specific_values["priority"] = priority
-        condition = self.getconditionContent()
-        specific_values["condition_type"] = condition["type"]
-        if specific_values["condition_type"] == "connection":
-            specific_values["connection"] = _getconnectioninfos(self, condition["value"], True)
-        else:
-            specific_values["condition"] = condition["value"]
-        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
-        return infos
-    setattr(cls, "getinfos", getinfos)
-
     def setconditionContent(self, condition_type, value):
         if self.condition is None:
             self.addcondition()
@@ -2278,32 +2084,8 @@
         return search_result
     setattr(cls, "Search", Search)
     
-cls = _initElementClass("selectionDivergence", "sfcObjects", "single")
-if cls:
-    setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False))
-
-cls = _initElementClass("selectionConvergence", "sfcObjects", "multiple")
-if cls:
-    setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False))
-
-cls = _initElementClass("simultaneousDivergence", "sfcObjects", "single")
-if cls:
-    setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True))
-
-cls = _initElementClass("simultaneousConvergence", "sfcObjects", "multiple")
-if cls:
-    setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True))
-
 cls = _initElementClass("jumpStep", "sfcObjects", "single")
 if cls:
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = "jump"
-        infos["specific_values"]["target"] = self.gettargetName()
-        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        return infos
-    setattr(cls, "getinfos", getinfos)
-
     def Search(self, criteria, parent_infos):
         return _Search([("target", self.gettargetName())], criteria, parent_infos + ["jump", self.getlocalId()])
     setattr(cls, "Search", Search)
@@ -2361,14 +2143,6 @@
 
 cls = _initElementClass("actionBlock", "commonObjects", "single")
 if cls:
-    def getinfos(self):
-        infos = _getelementinfos(self)
-        infos["type"] = "actionBlock"
-        infos["specific_values"]["actions"] = self.getactions()
-        infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
-        return infos
-    setattr(cls, "getinfos", getinfos)
-    
     def setactions(self, actions):
         self.action = []
         for params in actions:
@@ -2440,21 +2214,18 @@
 
 cls = _initElementClass("inVariable", "fbdObjects")
 if cls:
-    setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True))
     setattr(cls, "updateElementName", _UpdateIOElementName)
     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
     setattr(cls, "Search", _SearchInIOVariable)
 
 cls = _initElementClass("outVariable", "fbdObjects", "single")
 if cls:
-    setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False))
     setattr(cls, "updateElementName", _UpdateIOElementName)
     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
     setattr(cls, "Search", _SearchInIOVariable)
 
 cls = _initElementClass("inOutVariable", "fbdObjects", "single")
 if cls:
-    setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True))
     setattr(cls, "updateElementName", _UpdateIOElementName)
     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
     setattr(cls, "Search", _SearchInIOVariable)
@@ -2465,7 +2236,6 @@
 
 cls = _initElementClass("continuation", "commonObjects")
 if cls:
-    setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))
     setattr(cls, "Search", _SearchInConnector)
 
     def updateElementName(self, old_name, new_name):
@@ -2475,7 +2245,6 @@
 
 cls = _initElementClass("connector", "commonObjects", "single")
 if cls:
-    setattr(cls, "getinfos", _getconnectorinfosFunction("connector"))
     setattr(cls, "Search", _SearchInConnector)
 
     def updateElementName(self, old_name, new_name):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/pou_block_instances.xslt	Wed Oct 02 01:21:35 2013 +0200
@@ -0,0 +1,1 @@
+<xsl:stylesheet xmlns:func="http://exslt.org/functions" xmlns:dyn="http://exslt.org/dynamic" xmlns:str="http://exslt.org/strings" xmlns:math="http://exslt.org/math" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="ns" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:yml="http://fdik.org/yml" xmlns:set="http://exslt.org/sets" version="1.0" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="pou_block_instances_ns" exclude-result-prefixes="ns" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml"/><xsl:variable name="space" select="'                                                                                                                                                                                                        '"/><xsl:param name="autoindent" select="4"/><xsl:template match="text()"><xsl:param name="_indent" select="0"/></xsl:template><xsl:template match="ppx:pou"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="ppx:body/*[self::ppx:FBD or self::ppx:LD or self::ppx:SFC]/*"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template name="add_instance"><xsl:param name="_indent" select="0"/><xsl:param name="type"/><xsl:variable name="instance"><xsl:value-of select="ns:AddBlockInstance($type, @localId, ppx:position/@x, ppx:position/@y, @width, @height)"/></xsl:variable></xsl:template><xsl:template name="execution_order"><xsl:param name="_indent" select="0"/><xsl:choose><xsl:when test="@executionOrderId"><xsl:value-of select="@executionOrderId"/></xsl:when><xsl:otherwise><xsl:text>0</xsl:text></xsl:otherwise></xsl:choose></xsl:template><xsl:template name="ConnectionInfos"><xsl:param name="_indent" select="0"/><xsl:param name="type"/><xsl:param name="modifiers"/><xsl:param name="formalParameter"/><xsl:variable name="negated"><xsl:choose><xsl:when test="$modifiers='input'"><xsl:value-of select="@negatedIn"/></xsl:when><xsl:when test="$modifiers='output'"><xsl:value-of select="@negatedOut"/></xsl:when><xsl:otherwise><xsl:value-of select="@negated"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="edge"><xsl:choose><xsl:when test="$modifiers='input'"><xsl:value-of select="@edgeIn"/></xsl:when><xsl:when test="$modifiers='output'"><xsl:value-of select="@edgeOut"/></xsl:when><xsl:otherwise><xsl:value-of select="@edge"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="instance_connection"><xsl:value-of select="ns:AddInstanceConnection($type, $formalParameter, $negated, $edge, ppx:relPosition/@x, ppx:relPosition/@y)"/></xsl:variable></xsl:template><xsl:template match="ppx:position"><xsl:param name="_indent" select="0"/><xsl:variable name="link_point"><xsl:value-of select="ns:AddLinkPoint(@x, @y)"/></xsl:variable></xsl:template><xsl:template match="ppx:connection"><xsl:param name="_indent" select="0"/><xsl:variable name="connection_link"><xsl:value-of select="ns:AddConnectionLink(@refLocalId, @formalParameter)"/></xsl:variable><xsl:apply-templates select="ppx:position"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:connectionPointIn"><xsl:param name="_indent" select="0"/><xsl:param name="modifiers"/><xsl:param name="formalParameter"/><xsl:call-template name="ConnectionInfos"><xsl:with-param name="type"><xsl:text>input</xsl:text></xsl:with-param><xsl:with-param name="modifiers"><xsl:value-of select="$modifiers"/></xsl:with-param><xsl:with-param name="formalParameter"><xsl:value-of select="$formalParameter"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connection"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:connectionPointOut"><xsl:param name="_indent" select="0"/><xsl:param name="modifiers"/><xsl:param name="formalParameter"/><xsl:call-template name="ConnectionInfos"><xsl:with-param name="type"><xsl:text>output</xsl:text></xsl:with-param><xsl:with-param name="modifiers"><xsl:value-of select="$modifiers"/></xsl:with-param><xsl:with-param name="formalParameter"><xsl:value-of select="$formalParameter"/></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:connectionPointOutAction"><xsl:param name="_indent" select="0"/><xsl:call-template name="ConnectionInfos"><xsl:with-param name="type"><xsl:text>output</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:comment"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(ppx:content/xhtml:p/text())"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:block"><xsl:param name="_indent" select="0"/><xsl:variable name="execution_order"><xsl:call-template name="execution_order"></xsl:call-template></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(@instanceName, $execution_order)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="@typeName"/></xsl:with-param></xsl:call-template><xsl:for-each select="ppx:inputVariables/ppx:variable"><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/><xsl:with-param name="formalParameter"><xsl:value-of select="@formalParameter"/></xsl:with-param></xsl:apply-templates></xsl:for-each><xsl:for-each select="ppx:outputVariables/ppx:variable"><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/><xsl:with-param name="formalParameter"><xsl:value-of select="@formalParameter"/></xsl:with-param></xsl:apply-templates></xsl:for-each></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived"><xsl:param name="_indent" select="0"/><xsl:value-of select="@name"/></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string"><xsl:param name="_indent" select="0"/><xsl:text>STRING</xsl:text></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring"><xsl:param name="_indent" select="0"/><xsl:text>WSTRING</xsl:text></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*"><xsl:param name="_indent" select="0"/><xsl:value-of select="local-name()"/></xsl:template><xsl:template name="VariableBlockInfos"><xsl:param name="_indent" select="0"/><xsl:param name="type"/><xsl:variable name="expression"><xsl:value-of select="ppx:expression/text()"/></xsl:variable><xsl:variable name="value_type"><xsl:choose><xsl:when test="ancestor::ppx:transition[@name=$expression]"><xsl:text>BOOL</xsl:text></xsl:when><xsl:when test="ancestor::ppx:pou[@name=$expression]"><xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface/ppx:returnType"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:when><xsl:otherwise><xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface/*/ppx:variable[@name=$expression]/ppx:type"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="execution_order"><xsl:call-template name="execution_order"></xsl:call-template></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues($expression, $value_type, $execution_order)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/><xsl:with-param name="modifiers"><xsl:choose><xsl:when test="$type='inout'"><xsl:text>input</xsl:text></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:with-param></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/><xsl:with-param name="modifiers"><xsl:choose><xsl:when test="$type='inout'"><xsl:text>output</xsl:text></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:with-param></xsl:apply-templates></xsl:template><xsl:template match="ppx:inVariable"><xsl:param name="_indent" select="0"/><xsl:call-template name="VariableBlockInfos"><xsl:with-param name="type" select="'input'"/></xsl:call-template></xsl:template><xsl:template match="ppx:outVariable"><xsl:param name="_indent" select="0"/><xsl:call-template name="VariableBlockInfos"><xsl:with-param name="type" select="'output'"/></xsl:call-template></xsl:template><xsl:template match="ppx:inOutVariable"><xsl:param name="_indent" select="0"/><xsl:call-template name="VariableBlockInfos"><xsl:with-param name="type" select="'inout'"/></xsl:call-template></xsl:template><xsl:template match="ppx:connector|ppx:continuation"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(@name)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:leftPowerRail|ppx:rightPowerRail"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="connectors"><xsl:choose><xsl:when test="$type='leftPowerRail'"><xsl:value-of select="count(ppx:connectionPointOut)"/></xsl:when><xsl:otherwise><xsl:value-of select="count(ppx:connectionPointIn)"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues($connectors)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:choose><xsl:when test="$type='leftPowerRail'"><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:when><xsl:otherwise><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:otherwise></xsl:choose></xsl:template><xsl:template match="ppx:contact|ppx:coil"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="storage"><xsl:choose><xsl:when test="$type='coil'"><xsl:value-of select="@storage"/></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="execution_order"><xsl:call-template name="execution_order"></xsl:call-template></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(ppx:variable/text(), @negated, @edge, $storage, $execution_order)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:step"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(@name, @initialStep)"/></xsl:variable><xsl:apply-templates select="ppx:connectionPointOutAction"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:transition"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="priority"><xsl:choose><xsl:when test="@priority"><xsl:value-of select="@priority"/></xsl:when><xsl:otherwise><xsl:text>0</xsl:text></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="condition_type"><xsl:choose><xsl:when test="ppx:condition/ppx:connectionPointIn"><xsl:text>connection</xsl:text></xsl:when><xsl:when test="ppx:condition/ppx:reference"><xsl:text>reference</xsl:text></xsl:when><xsl:when test="ppx:condition/ppx:inline"><xsl:text>inline</xsl:text></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="condition"><xsl:choose><xsl:when test="ppx:reference"><xsl:value-of select="ppx:condition/ppx:reference/@name"/></xsl:when><xsl:when test="ppx:inline"><xsl:value-of select="ppx:condition/ppx:inline/ppx:body/ppx:ST/xhtml:p/text()"/></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues($priority, $condition_type, $condition)"/></xsl:variable><xsl:apply-templates select="ppx:condition/ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:selectionDivergence|ppx:selectionConvergence|ppx:simultaneousDivergence|ppx:simultaneousConvergence"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="connectors"><xsl:choose><xsl:when test="ppx:selectionDivergence|ppx:simultaneousDivergence"><xsl:value-of select="count(ppx:connectionPointOut)"/></xsl:when><xsl:otherwise><xsl:value-of select="count(ppx:connectionPointIn)"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues($connectors)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:apply-templates select="ppx:connectionPointOut"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:jumpStep"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:text>jump</xsl:text></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues(@targetName)"/></xsl:variable><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:action"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:choose><xsl:when test="ppx:reference"><xsl:text>reference</xsl:text></xsl:when><xsl:when test="ppx:inline"><xsl:text>inline</xsl:text></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="value"><xsl:choose><xsl:when test="ppx:reference"><xsl:value-of select="ppx:reference/@name"/></xsl:when><xsl:when test="ppx:inline"><xsl:value-of select="ppx:inline/ppx:ST/xhtml:p/text()"/></xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="actionBlock_action"><xsl:value-of select="ns:AddAction(@qualifier, $type, $value, @duration, @indicator)"/></xsl:variable></xsl:template><xsl:template match="ppx:actionBlock"><xsl:param name="_indent" select="0"/><xsl:variable name="type"><xsl:value-of select="local-name()"/></xsl:variable><xsl:variable name="instance_specific_values"><xsl:value-of select="ns:SetSpecificValues()"/></xsl:variable><xsl:apply-templates select="ppx:action"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:call-template name="add_instance"><xsl:with-param name="type"><xsl:value-of select="$type"/></xsl:with-param></xsl:call-template><xsl:apply-templates select="ppx:connectionPointIn"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template></xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/pou_block_instances.ysl2	Wed Oct 02 01:21:35 2013 +0200
@@ -0,0 +1,358 @@
+include yslt.yml2
+estylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
+            xmlns:xhtml="http://www.w3.org/1999/xhtml"
+            xmlns:ns="pou_block_instances_ns" 
+            extension-element-prefixes="ns" 
+            exclude-result-prefixes="ns" {
+
+    template "text()";
+    
+    template "ppx:pou" {
+        apply "ppx:body/*[self::ppx:FBD or self::ppx:LD or self::ppx:SFC]/*";
+    }
+    
+    function "add_instance" {
+        param "type";
+        variable "instance" {
+            > «ns:AddBlockInstance($type, @localId, ppx:position/@x, ppx:position/@y, @width, @height)»
+        }
+    }
+    
+    function "execution_order" {
+        choose {
+            when "@executionOrderId" > «@executionOrderId»
+            otherwise > 0
+        }
+    }
+    
+    function "ConnectionInfos" {
+        param "type";
+        param "modifiers";
+        param "formalParameter";
+        variable "negated" {
+            choose {
+                when "$modifiers='input'" > «@negatedIn»
+                when "$modifiers='output'" > «@negatedOut»
+                otherwise > «@negated»
+            }
+        }
+        variable "edge" {
+            choose {
+                when "$modifiers='input'" > «@edgeIn»
+                when "$modifiers='output'" > «@edgeOut»
+                otherwise > «@edge»
+            }
+        }
+        variable "instance_connection" {
+            > «ns:AddInstanceConnection($type, $formalParameter, $negated, $edge, ppx:relPosition/@x, ppx:relPosition/@y)»
+        }
+    }
+    
+    template "ppx:position" {
+        variable "link_point" {
+            > «ns:AddLinkPoint(@x, @y)»
+        }
+    }
+    
+    template "ppx:connection" {
+        variable "connection_link" {
+            > «ns:AddConnectionLink(@refLocalId, @formalParameter)»
+        }
+        apply "ppx:position";
+    }
+    
+    template "ppx:connectionPointIn" {
+        param "modifiers";
+        param "formalParameter";
+        call "ConnectionInfos" {
+            with "type" > input
+            with "modifiers" > «$modifiers»
+            with "formalParameter" > «$formalParameter»
+        }
+        apply "ppx:connection";
+    }
+    
+    template "ppx:connectionPointOut" {
+        param "modifiers";
+        param "formalParameter";
+        call "ConnectionInfos" {
+            with "type" > output
+            with "modifiers" > «$modifiers»
+            with "formalParameter" > «$formalParameter»
+        }
+    }
+    
+    template "ppx:connectionPointOutAction" {
+        call "ConnectionInfos" {
+            with "type" > output
+        }
+    }
+    
+    template "ppx:comment" {
+        variable "type" > «local-name()»
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(ppx:content/xhtml:p/text())»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+    }
+    
+    template "ppx:block" {
+        variable "execution_order" {
+            call "execution_order";
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(@instanceName, $execution_order)»
+        }
+        call "add_instance" {
+            with "type" > «@typeName»
+        }
+        foreach "ppx:inputVariables/ppx:variable" {
+            apply "ppx:connectionPointIn" {
+                with "formalParameter" > «@formalParameter»
+            }
+        }
+        foreach "ppx:outputVariables/ppx:variable" {
+            apply "ppx:connectionPointOut" {
+                with "formalParameter" > «@formalParameter»
+            }
+        }
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived" {
+        > «@name»
+    }
+  
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string" {
+        > STRING
+    }
+  
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring" {
+        > WSTRING
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*" {
+        > «local-name()»
+    }
+    
+    function "VariableBlockInfos" {
+        param "type";
+        variable "expression" > «ppx:expression/text()»
+        variable "value_type" {
+            choose {
+                when "ancestor::ppx:transition[@name=$expression]" > BOOL
+                when "ancestor::ppx:pou[@name=$expression]" {
+                    apply "ancestor::ppx:pou/child::ppx:interface/ppx:returnType"
+                }
+                otherwise {
+                    apply "ancestor::ppx:pou/child::ppx:interface/*/ppx:variable[@name=$expression]/ppx:type"
+                }
+            }
+        }
+        variable "execution_order" {
+            call "execution_order";
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues($expression, $value_type, $execution_order)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn" {
+            with "modifiers" {
+                choose {
+                    when "$type='inout'" > input
+                    otherwise > 
+                }
+            }
+        }
+        apply "ppx:connectionPointOut" {
+            with "modifiers" {
+                choose {
+                    when "$type='inout'" > output
+                    otherwise > 
+                }
+            }
+        }
+    }
+    
+    template "ppx:inVariable" {
+        call "VariableBlockInfos" with "type", "'input'";
+    }
+    
+    template "ppx:outVariable" {
+        call "VariableBlockInfos" with "type", "'output'";
+    }
+    
+    template "ppx:inOutVariable" {
+        call "VariableBlockInfos" with "type", "'inout'";
+    }
+    
+    template "ppx:connector|ppx:continuation" {
+        variable "type" > «local-name()»
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(@name)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+        apply "ppx:connectionPointOut";
+    }
+    
+    template "ppx:leftPowerRail|ppx:rightPowerRail" {
+        variable "type" > «local-name()»
+        variable "connectors" {
+            choose {
+                when "$type='leftPowerRail'" > «count(ppx:connectionPointOut)»
+                otherwise > «count(ppx:connectionPointIn)»
+            }
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues($connectors)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        choose {
+            when "$type='leftPowerRail'" {
+                apply "ppx:connectionPointOut";
+            }
+            otherwise {
+                apply "ppx:connectionPointIn";
+            }
+        }
+    }
+    
+    template "ppx:contact|ppx:coil" {
+        variable "type" > «local-name()»
+        variable "storage" {
+            choose {
+                when "$type='coil'" > «@storage»
+                otherwise > 
+            }
+        }
+        variable "execution_order" {
+            call "execution_order";
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(ppx:variable/text(), @negated, @edge, $storage, $execution_order)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+        apply "ppx:connectionPointOut";
+    }
+    
+    template "ppx:step" {
+        variable "type" > «local-name()»
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(@name, @initialStep)»
+        }
+        apply "ppx:connectionPointOutAction";
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+        apply "ppx:connectionPointOut";
+    }
+    
+    template "ppx:transition" {
+        variable "type" > «local-name()»
+        variable "priority" {
+            choose {
+                when "@priority" > «@priority»
+                otherwise > 0
+            }
+        }
+        variable "condition_type" {
+            choose {
+                when "ppx:condition/ppx:connectionPointIn" > connection
+                when "ppx:condition/ppx:reference" > reference
+                when "ppx:condition/ppx:inline" > inline
+                otherwise > 
+            }
+        }
+        variable "condition" {
+            choose {
+                when "ppx:reference" > «ppx:condition/ppx:reference/@name»
+                when "ppx:inline" > «ppx:condition/ppx:inline/ppx:body/ppx:ST/xhtml:p/text()»
+                otherwise > 
+            }
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues($priority, $condition_type, $condition)»
+        }
+        apply "ppx:condition/ppx:connectionPointIn";
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+        apply "ppx:connectionPointOut";
+    }
+    
+    template "ppx:selectionDivergence|ppx:selectionConvergence|ppx:simultaneousDivergence|ppx:simultaneousConvergence" {
+        variable "type" > «local-name()»
+        variable "connectors" {
+            choose {
+                when "ppx:selectionDivergence|ppx:simultaneousDivergence" {
+                    > «count(ppx:connectionPointOut)»
+                }
+                otherwise > «count(ppx:connectionPointIn)»
+            }
+        }
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues($connectors)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+        apply "ppx:connectionPointOut";
+    }
+    
+    template "ppx:jumpStep" {
+        variable "type" > jump
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues(@targetName)»
+        }
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+    }
+    
+    template "ppx:action" {
+        variable "type" {
+            choose {
+                when "ppx:reference" > reference
+                when "ppx:inline" > inline
+                otherwise > 
+            }
+        }
+        variable "value" {
+            choose {
+                when "ppx:reference" > «ppx:reference/@name»
+                when "ppx:inline" > «ppx:inline/ppx:ST/xhtml:p/text()»
+                otherwise > 
+            }
+        }
+        variable "actionBlock_action" {
+            > «ns:AddAction(@qualifier, $type, $value, @duration, @indicator)»
+        }
+    }
+    
+    template "ppx:actionBlock" {
+        variable "type" > «local-name()»
+        variable "instance_specific_values" {
+            > «ns:SetSpecificValues()»
+        }
+        apply "ppx:action";
+        call "add_instance" {
+            with "type" > «$type»
+        }
+        apply "ppx:connectionPointIn";
+    }
+}
\ No newline at end of file