Added a class to speedup all XSLT queries. WIP, now only for instances_path.xslt / GetInstanceList()
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Fri, 16 Feb 2018 13:00:06 +0100
changeset 1939 db478d17bc3a
parent 1938 87136f8697e3
child 1940 8dc4ebc97777
Added a class to speedup all XSLT queries. WIP, now only for instances_path.xslt / GetInstanceList()
PLCControler.py
plcopen/instances_path.xslt
plcopen/instances_path.ysl2
--- a/PLCControler.py	Fri Feb 16 03:24:11 2018 +0100
+++ b/PLCControler.py	Fri Feb 16 13:00:06 2018 +0100
@@ -267,47 +267,51 @@
                     [_BoolValue] * 2, args) + [[]])))
 
 
-class InstancesPathCollector(object):
+class XSLTModelQuery(object):
+    """ a class to handle XSLT queries on project and libs """
+    def __init__(self, controller, xsltpath, ext = []):
+        # arbitrary set debug to false, updated later
+        self.debug = False
+
+        # merge xslt extensions for library access to query specific ones
+        xsltext = [
+            ("GetProject", lambda *_ignored: 
+                controller.GetProject(self.debug)),
+            ("GetStdLibs", lambda *_ignored: 
+                [lib for lib in StdBlckLibs.values()]),
+            ("GetExtensions", lambda *_ignored: 
+                [ctn["types"] for ctn in controller.ConfNodeTypes])
+        ] + ext
+
+        # parse and compile. "beremiz" arbitrary namespace for extensions 
+        self.xslt = etree.XSLT(
+            etree.parse(
+                os.path.join(ScriptDirectory, "plcopen", xsltpath),
+                etree.XMLParser()),
+            extensions={ ("beremiz", name):call for name, call in xsltext})
+
+    def _process_xslt(self, root, debug, **kwargs):
+        self.debug = debug
+        return self.xslt(root,**{k:etree.XSLT.strparam(v) for k,v in kwargs.iteritems()})
+
+class InstancesPathCollector(XSLTModelQuery):
     """ object for collecting instances path list"""
     def __init__(self, controller):
         self.Instances = []
-        self.controller = controller
-        parser = etree.XMLParser()
-        # arbitrary set debug to false, updated later
-        self.debug = False
-
-        # TODO compile XSLT once for all at __init__
-        self.instances_path_xslt_tree = etree.XSLT(
-            etree.parse(
-                os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
-                parser),
-            extensions={
-                ("instances_ns", "AddInstance"): self.AddInstance,
-                ("instances_ns", "GetProject"): self.GetProject,
-                ("instances_ns", "GetStdLibs"): self.GetStdLibs,
-                ("instances_ns", "GetExtensions"): self.GetExtensions})
+        XSLTModelQuery.__init__(self,
+                                controller,
+                                "instances_path.xslt",
+                                [("AddInstance", self.AddInstance)])
 
     def AddInstance(self, context, *args):
         self.Instances.append(args[0][0])
 
-    def GetProject(self, context, *args):
-        return self.controller.GetProject(self.debug)
-
-    def GetStdLibs(self, context, *args):
-        return [lib for lib in StdBlckLibs.values()]
-
-    def GetExtensions(self, context, *args):
-        return [ctn["types"] for ctn in self.controller.ConfNodeTypes]
-
     def Collect(self, root, name, debug):
-        self.debug = debug
-        self.instances_path_xslt_tree(
-            root, instance_type=etree.XSLT.strparam(name))
+        self._process_xslt(root, debug, instance_type = name)
         res = self.Instances
         self.Instances = []
         return res
 
-
 class InstanceTagName(object):
     """Helpers object for generating instance tagname"""
 
@@ -837,10 +841,7 @@
         return None
 
     def GetInstanceList(self, root, name, debug=False):
-        project = self.GetProject(debug)
-        if project is not None:
-            return self.InstancesPathCollector.Collect(root, name, debug)
-        return []
+        return self.InstancesPathCollector.Collect(root, name, debug)
 
     def SearchPouInstances(self, tagname, debug=False):
         project = self.GetProject(debug)
--- a/plcopen/instances_path.xslt	Fri Feb 16 03:24:11 2018 +0100
+++ b/plcopen/instances_path.xslt	Fri Feb 16 13:00:06 2018 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="instances_ns" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="beremiz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
   <xsl:output method="xml"/>
   <xsl:param name="instance_type"/>
   <xsl:template match="text()"/>
--- a/plcopen/instances_path.ysl2	Fri Feb 16 03:24:11 2018 +0100
+++ b/plcopen/instances_path.ysl2	Fri Feb 16 13:00:06 2018 +0100
@@ -1,7 +1,7 @@
 include yslt_noindent.yml2
 istylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
             xmlns:xhtml="http://www.w3.org/1999/xhtml"
-            xmlns:ns="instances_ns" 
+            xmlns:ns="beremiz" 
             extension-element-prefixes="ns" 
             exclude-result-prefixes="ns" {
     
@@ -17,6 +17,7 @@
 
     variable "all", "$project | $stdlib | $extensions";
     
+
     template "ppx:project" {
         apply "ppx:instances/ppx:configurations/ppx:configuration";
     }