I am new to XSLT transformations. I am writing some transformations in order to refactor code expressed in srcML and I am facing a problem. The XML input I am working with looks like this:
....
<function><type><name>void</name></type> <name>DrawHorizontal</name>
<parameter_list>(
<param><decl><type><name>t_paper</name></type> <name>p</name></decl></param>,
<param><decl><type><name>int</name></type> <name>x</name></decl></param>,
<param><decl><type><name>int</name></type> <name>y</name></decl></param>)
</parameter_list>
<block>{.....
<expr_stmt><expr>
<name>
<name>p</name>
<index>[<expr><name>x</name></expr>]</index>
<index>[<expr><name>y</name></expr>]</index>
</name>.
<name>hor</name>
<operator>=</operator> 1
</expr>;</expr_stmt>
...
}</block>
</function>
What I want to do is, for each function section:
1) Identify the name of the parameters of a certain type (p of type t_paper for example)
2) Change the expression statement where the parameters, identified in the previous step, are found ()
The output should look like this:
.....
<function><type><name>void</name></type> <name>DrawHorizontal</name>
<parameter_list>(
<param><decl><type><name>t_paper</name></type> <name>p</name></decl></param>,
<param><decl><type><name>int</name></type> <name>x</name></decl></param>,
<param><decl><type><name>int</name></type> <name>y</name></decl></param>)
</parameter_list>
<block>{.....
<expr_stmt><expr>
<name>p</name>.
<name>
<name>data</name>
<index>[<expr><name>x</name></expr>]</index>
<index>[<expr><name>y</name></expr>]</index>
</name>.
<name>hor</name>
<operator>=</operator> 1
</expr>;</expr_stmt>
...
}</block>
</function>
In summary, I need to transform expr_stmt nodes only where parameters of a certain type are found (t_paper in the example). The rest of the file should be copied as it is.
My problem is that I am not able to apply templates to that specific sections based on the dynamically created conditions (the names of the parameters).
Some NOT working code is the following:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="//function">
<xsl:choose>
<xsl:when test="parameter_list/param/decl/type/name='t_paper'">
<xsl:copy>
<xsl:call-template name="transform-function" select="node()">
<xsl:with-param name="appearance" select="parameter_list/param/decl/name" />
</xsl:call-template>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<function><xsl:apply-templates select="node()"/></function>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="transform-function">
<xsl:param name="appearance" />
<xsl:if test="//expr_stmt/expr/name/name=$appearance">
substitution here
</xsl:if>
</xsl:template>
</xsl:stylesheet>
I would be very grateful if someone could give me a hint.
Please let me know if you need more details as this is my first question in SO.
Cheers,
D.
This simple transformation (no explicit conditionals at all):
when applied on the provided XML document:
produces the wanted result:
Explanation:
Overriding the identity rule just for parameters that are of the requested type.
Using a key to conveniently define the mapping between a parameter declaration and its (name, type)