# HG changeset patch # User Laurent Bessard # Date 1380703578 -7200 # Node ID 43ab74687f4502216e1369a479fed8791ca7c54f # Parent 4bea1d98db467ed070de845d9a9e75c36108232d Fixed xslt stylesheet for extracting entries defined in module, rewiting xslt stylesheet to yslt diff -r 4bea1d98db46 -r 43ab74687f45 etherlab/entries_list.xslt --- 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 diff -r 4bea1d98db46 -r 43ab74687f45 etherlab/entries_list.ysl2 --- /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 diff -r 4bea1d98db46 -r 43ab74687f45 etherlab/etherlab.py --- 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(