Fixed xslt stylesheet for extracting entries defined in module, rewiting xslt stylesheet to yslt
--- a/etherlab/entries_list.xslt Mon Sep 30 13:43:02 2013 +0200
+++ b/etherlab/entries_list.xslt Wed Oct 02 10:46:18 2013 +0200
@@ -1,123 +1,1 @@
-<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:ns="entries_list_ns"
- extension-element-prefixes="ns"
- exclude-result-prefixes="ns">
- <xsl:param name="min_index"/>
- <xsl:param name="max_index"/>
- <xsl:template match="Device">
- <xsl:apply-templates select="Profile/Dictionary/Objects/Object"/>
- <xsl:for-each select="RxPdo">
- <xsl:call-template name="pdo_entries">
- <xsl:with-param name="direction" select="'Receive'"/>
- </xsl:call-template>
- </xsl:for-each>
- <xsl:for-each select="TxPdo">
- <xsl:call-template name="pdo_entries">
- <xsl:with-param name="direction" select="'Transmit'"/>
- </xsl:call-template>
- </xsl:for-each>
- </xsl:template>
- <xsl:template match="Object">
- <xsl:variable name="index">
- <xsl:value-of select="ns:HexDecValue(Index/text())"/>
- </xsl:variable>
- <xsl:variable name="entry_name">
- <xsl:value-of select="ns:EntryName(Name)"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$index >= $min_index and $index <= $max_index">
- <xsl:variable name="datatype_name">
- <xsl:value-of select="Type/text()"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]">
- <xsl:apply-templates select="ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]">
- <xsl:with-param name="index">
- <xsl:value-of select="$index"/>
- </xsl:with-param>
- <xsl:with-param name="entry_name">
- <xsl:value-of select="$entry_name"/>
- </xsl:with-param>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <ns:add_entry>
- <Index><xsl:value-of select="$index"/></Index>
- <SubIndex><xsl:text>0</xsl:text></SubIndex>
- <Name><xsl:value-of select="$entry_name"/></Name>
- <Type><xsl:value-of select="$datatype_name"/></Type>
- <BitSize><xsl:value-of select="BitSize/text()"/></BitSize>
- <Access><xsl:value-of select="Flags/Access/text()"/></Access>
- <PDOMapping><xsl:value-of select="Flags/PdoMapping/text()"/></PDOMapping>
- </ns:add_entry>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="DataType">
- <xsl:param name="index"/>
- <xsl:param name="entry_name"/>
- <xsl:for-each select="SubItem">
- <xsl:variable name="subentry_names">
- <xsl:value-of select="DisplayName"/>
- <Default><xsl:value-of select="Name/text()"/></Default>
- </xsl:variable>
- <ns:add_entry>
- <Index><xsl:value-of select="$index"/></Index>
- <SubIndex><xsl:value-of select="ns:HexDecValue(SubIdx/text())"/></SubIndex>
- <Name>
- <xsl:value-of select="$entry_name"/>
- <xsl:text> - </xsl:text>
- <xsl:value-of select="ns:EntryName($subentry_names)"/>
- </Name>
- <Type><xsl:value-of select="Type/text()"/></Type>
- <BitSize><xsl:value-of select="BitSize/text()"/></BitSize>
- <Access><xsl:value-of select="Flags/Access/text()"/></Access>
- <PDOMapping><xsl:value-of select="Flags/PdoMapping/text()"/></PDOMapping>
- </ns:add_entry>
- </xsl:for-each>
- </xsl:template>
- <xsl:template name="pdo_entries">
- <xsl:param name="direction"/>
- <xsl:variable name="pdo_index">
- <xsl:value-of select="ns:HexDecValue(Index/text())"/>
- </xsl:variable>
- <xsl:variable name="pdo_name">
- <xsl:value-of select="ns:EntryName(Name)"/>
- </xsl:variable>
- <xsl:for-each select="Entry">
- <xsl:variable name="index">
- <xsl:value-of select="ns:HexDecValue(Index/text())"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$index >= $min_index and $index <= $max_index">
- <ns:add_entry>
- <Index><xsl:value-of select="$index"/></Index>
- <SubIndex><xsl:value-of select="ns:HexDecValue(SubIndex/text())"/></SubIndex>
- <Name><xsl:value-of select="ns:EntryName(Name)"/></Name>
- <Type><xsl:value-of select="DataType/text()"/></Type>
- <BitSize><xsl:value-of select="BitLen/text()"/></BitSize>
- <xsl:choose>
- <xsl:when test="$direction='Transmit'">
- <Access><xsl:text>ro</xsl:text></Access>
- <PDOMapping><xsl:text>T</xsl:text></PDOMapping>
- </xsl:when>
- <xsl:otherwise>
- <Access><xsl:text>wo</xsl:text></Access>
- <PDOMapping><xsl:text>R</xsl:text></PDOMapping>
- </xsl:otherwise>
- </xsl:choose>
- <PDO>
- <index><xsl:value-of select="$pdo_index"/></index>
- <name><xsl:value-of select="$pdo_name"/></name>
- <type><xsl:value-of select="$direction"/></type>
- </PDO>
- </ns:add_entry>
- </xsl:when>
- </xsl:choose>
- </xsl:for-each>
- </xsl:template>
- <xsl:template match="text()"/>
-</xsl:stylesheet>
\ No newline at end of file
+<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:yml="http://fdik.org/yml" xmlns:set="http://exslt.org/sets" version="1.0" xmlns:ns="entries_list_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:param name="min_index"/><xsl:param name="max_index"/><xsl:template match="text()"><xsl:param name="_indent" select="0"/></xsl:template><xsl:template match="Device"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="Profile/Dictionary/Objects/Object"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:for-each select="RxPdo"><xsl:call-template name="pdo_entries"><xsl:with-param name="direction" select="'Receive'"/></xsl:call-template></xsl:for-each><xsl:for-each select="TxPdo"><xsl:call-template name="pdo_entries"><xsl:with-param name="direction" select="'Transmit'"/></xsl:call-template></xsl:for-each></xsl:template><xsl:template match="Object"><xsl:param name="_indent" select="0"/><xsl:variable name="index"><xsl:value-of select="ns:HexDecValue(Index/text())"/></xsl:variable><xsl:variable name="entry_name"><xsl:value-of select="ns:EntryName(Name)"/></xsl:variable><xsl:choose><xsl:when test="$index >= $min_index and $index <= $max_index"><xsl:variable name="datatype_name"><xsl:value-of select="Type/text()"/></xsl:variable><xsl:choose><xsl:when test="ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]"><xsl:apply-templates select="ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/><xsl:with-param name="index"><xsl:value-of select="$index"/></xsl:with-param><xsl:with-param name="entry_name"><xsl:value-of select="$entry_name"/></xsl:with-param></xsl:apply-templates></xsl:when><xsl:otherwise><xsl:variable name="subindex"><xsl:text>0</xsl:text></xsl:variable><xsl:variable name="entry"><xsl:value-of select="ns:AddEntry($index, $subindex, $entry_name, $datatype_name, BitSize/text(), Flags/Access/text(), Flags/PdoMapping/text())"/></xsl:variable></xsl:otherwise></xsl:choose></xsl:when></xsl:choose></xsl:template><xsl:template match="DataType"><xsl:param name="_indent" select="0"/><xsl:param name="index"/><xsl:param name="entry_name"/><xsl:for-each select="SubItem"><xsl:variable name="subindex"><xsl:value-of select="ns:HexDecValue(SubIdx/text())"/></xsl:variable><xsl:variable name="subentry_name"><xsl:value-of select="$entry_name"/><xsl:text> - </xsl:text><xsl:value-of select="ns:EntryName(DisplayName, Name/text())"/></xsl:variable><xsl:variable name="entry"><xsl:value-of select="ns:AddEntry($index, $subindex, $subentry_name, Type/text(), BitSize/text(), Flags/Access/text(), Flags/PdoMapping/text())"/></xsl:variable></xsl:for-each></xsl:template><xsl:template name="pdo_entries"><xsl:param name="_indent" select="0"/><xsl:param name="direction"/><xsl:variable name="pdo_index"><xsl:value-of select="ns:HexDecValue(Index/text())"/></xsl:variable><xsl:variable name="pdo_name"><xsl:value-of select="ns:EntryName(Name)"/></xsl:variable><xsl:for-each select="Entry"><xsl:variable name="index"><xsl:value-of select="ns:HexDecValue(Index/text())"/></xsl:variable><xsl:choose><xsl:when test="$index >= $min_index and $index <= $max_index"><xsl:variable name="subindex"><xsl:value-of select="ns:HexDecValue(SubIndex/text())"/></xsl:variable><xsl:variable name="subentry_name"><xsl:value-of select="ns:EntryName(Name)"/></xsl:variable><xsl:variable name="access"><xsl:choose><xsl:when test="$direction='Transmit'"><xsl:text>ro</xsl:text></xsl:when><xsl:otherwise><xsl:text>wo</xsl:text></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="pdo_mapping"><xsl:choose><xsl:when test="$direction='Transmit'"><xsl:text>T</xsl:text></xsl:when><xsl:otherwise><xsl:text>R</xsl:text></xsl:otherwise></xsl:choose></xsl:variable><xsl:variable name="entry"><xsl:value-of select="ns:AddEntry($index, $subindex, $subentry_name, DataType/text(), BitLen/text(), $access, $pdo_mapping, $pdo_index, $pdo_name, $direction)"/></xsl:variable></xsl:when></xsl:choose></xsl:for-each></xsl:template></xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/etherlab/entries_list.ysl2 Wed Oct 02 10:46:18 2013 +0200
@@ -0,0 +1,86 @@
+include yslt.yml2
+estylesheet xmlns:ns="entries_list_ns"
+ extension-element-prefixes="ns"
+ exclude-result-prefixes="ns" {
+
+ param "min_index";
+ param "max_index";
+
+ template "text()";
+
+ template "Device" {
+ apply "Profile/Dictionary/Objects/Object";
+ foreach "RxPdo" {
+ call "pdo_entries" with "direction", "'Receive'";
+ }
+ foreach "TxPdo" {
+ call "pdo_entries" with "direction", "'Transmit'";
+ }
+ }
+
+ template "Object" {
+ variable "index" > «ns:HexDecValue(Index/text())»
+ variable "entry_name" > «ns:EntryName(Name)»
+ choose {
+ when "$index >= $min_index and $index <= $max_index" {
+ variable "datatype_name" > «Type/text()»
+ choose {
+ when "ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]" {
+ apply "ancestor::Dictionary/child::DataTypes/DataType[Name/text()=$datatype_name][SubItem]" {
+ with "index" > «$index»
+ with "entry_name" > «$entry_name»
+ }
+ }
+ otherwise {
+ variable "subindex" > 0
+ variable "entry" {
+ > «ns:AddEntry($index, $subindex, $entry_name, $datatype_name, BitSize/text(), Flags/Access/text(), Flags/PdoMapping/text())»
+ }
+ }
+ }
+ }
+ }
+ }
+
+ template "DataType" {
+ param "index";
+ param "entry_name";
+ foreach "SubItem" {
+ variable "subindex" > «ns:HexDecValue(SubIdx/text())»
+ variable "subentry_name" > «$entry_name» - «ns:EntryName(DisplayName, Name/text())»
+ variable "entry" {
+ > «ns:AddEntry($index, $subindex, $subentry_name, Type/text(), BitSize/text(), Flags/Access/text(), Flags/PdoMapping/text())»
+ }
+ }
+ }
+
+ function "pdo_entries" {
+ param "direction";
+ variable "pdo_index" > «ns:HexDecValue(Index/text())»
+ variable "pdo_name" > «ns:EntryName(Name)»
+ foreach "Entry" {
+ variable "index" > «ns:HexDecValue(Index/text())»
+ choose {
+ when "$index >= $min_index and $index <= $max_index" {
+ variable "subindex" > «ns:HexDecValue(SubIndex/text())»
+ variable "subentry_name" > «ns:EntryName(Name)»
+ variable "access" {
+ choose {
+ when "$direction='Transmit'" > ro
+ otherwise > wo
+ }
+ }
+ variable "pdo_mapping" {
+ choose {
+ when "$direction='Transmit'" > T
+ otherwise > R
+ }
+ }
+ variable "entry" {
+ > «ns:AddEntry($index, $subindex, $subentry_name, DataType/text(), BitLen/text(), $access, $pdo_mapping, $pdo_index, $pdo_name, $direction)»
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- a/etherlab/etherlab.py Mon Sep 30 13:43:02 2013 +0200
+++ b/etherlab/etherlab.py Wed Oct 02 10:46:18 2013 +0200
@@ -22,60 +22,44 @@
EtherCATInfoParser = GenerateParserFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATInfo.xsd"))
EtherCATInfo_XPath = lambda xpath: etree.XPath(xpath)
-def extract_param(el):
- if el.tag == "Index":
- return "#x%4.4X" % int(el.text)
- elif el.tag == "BitSize":
- if el.text is None:
- return 0
- return int(el.text)
- elif el.tag == "PDOMapping":
- if el.text is None:
- return ""
- return el.text.upper()
- if el.text is None:
- return ""
- return el.text
-
-def extract_pdo_infos(pdo_infos):
- return {
- pdo_infos.tag + " " + el.tag: extract_param(el)
- for el in pdo_infos}
-
-def HexDecValue(ctxt, values):
- return str(ExtractHexDecValue(values[0]))
-
-def EntryName(ctxt, values):
- default=None
- names = []
- for element in values:
- if element.tag == "Default":
- default = element.text
- else:
- names.append(element)
- return ExtractName(names, default)
-
-class AddEntry(etree.XSLTExtension):
+def HexDecValue(context, *args):
+ return str(ExtractHexDecValue(args[0][0]))
+
+def EntryName(context, *args):
+ return ExtractName(args[0],
+ args[1][0] if len(args) > 1 else None)
+
+ENTRY_INFOS_KEYS = [
+ ("Index", lambda x: "#x%4.4X" % int(x), "#x0000"),
+ ("SubIndex", str, "0"),
+ ("Name", str, ""),
+ ("Type", str, ""),
+ ("BitSize", int, 0),
+ ("Access", str, ""),
+ ("PDOMapping", str, ""),
+ ("PDO index", str, ""),
+ ("PDO name", str, ""),
+ ("PDO type", str, "")]
+
+class EntryListFactory:
def __init__(self, entries):
- etree.XSLTExtension.__init__(self)
self.Entries = entries
- def execute(self, context, self_node, input_node, output_parent):
- infos = etree.Element('entry_infos')
- self.process_children(context, infos)
- index, subindex = map(
- lambda x: int(infos.find(x).text),
- ["Index", "SubIndex"])
+ def AddEntry(self, context, *args):
+ index, subindex = map(lambda x: int(x[0]), args[:2])
new_entry_infos = {
- el.tag: extract_param(el)
- for el in infos if el.tag != "PDO"}
+ key: translate(arg[0]) if len(arg) > 0 else default
+ for (key, translate, default), arg
+ in zip(ENTRY_INFOS_KEYS, args)}
+
if (index, subindex) != (0, 0):
entry_infos = self.Entries.get((index, subindex))
if entry_infos is not None:
- PDO_infos = infos.find("PDO")
- if PDO_infos is not None:
- entry_infos.update(extract_pdo_infos(PDO_infos))
+ for param in ["PDO index", "PDO name", "PDO type"]:
+ value = new_entry_infos.get(param)
+ if value is not None:
+ entry_infos[param] = value
else:
self.Entries[(index, subindex)] = new_entry_infos
@@ -100,9 +84,11 @@
def GetEntriesList(self, limits=None):
entries = {}
+ factory = EntryListFactory(entries)
+
entries_list_xslt_tree = etree.XSLT(
entries_list_xslt, extensions = {
- ("entries_list_ns", "add_entry"): AddEntry(entries),
+ ("entries_list_ns", "AddEntry"): factory.AddEntry,
("entries_list_ns", "HexDecValue"): HexDecValue,
("entries_list_ns", "EntryName"): EntryName})
entries_list_xslt_tree(self, **dict(zip(