I'm trying to find a solution for how to replace standard 3-line code of type "call-template" - "with-param" with one single line.
For example I have the following piece of code:
<xsl:call-template name="do_job">
<xsl:with-param name="str">data1</xsl:with-param>
</xsl:call-template>
that i want to replace with something like this:
<myNs:tr name="data1"/>
It is not possible to create and use macros in XSLT.
In XSLT 2.0 one can write functions using the <xsl:function>
instruction. Then a function is referenced in any XPath expression:
my:do_job(someString)
Here is a full example:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:template match="/">
<xsl:sequence select="my:do_job('Hello, World!')"/>
</xsl:template>
<xsl:function name="my:do_job" as="xs:integer">
<xsl:param name="pText" as="xs:string"/>
<xsl:sequence select="string-length($pText)"/>
</xsl:function>
</xsl:stylesheet>
when this transformation is applied on any XML document (not used), the correct result is produced:
13
As Dimitre already said, macros are not supported. You could however generate your XSLT on the fly from an XML document containing macros and then run the generated XSLT.
A stylesheet that would create your XSLT would look like this:
<xsl:template match="myNs:tr">
<xsl:call-template name="do_job">
<xsl:with-param name="str" select="{@name}" />
</xsl:call-template>
</xsl:template>
Beside Dimitre excellent answer and recomendation, you could something like this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myNs="myNs"
exclude-result-prefixes="myNs">
<myNs:tr name="data1"/>
<myNs:tr name="data2"/>
<xsl:template match="root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="data">
<data>
<macro>
<xsl:apply-templates select="document('')/*/myNs:*
[@name=current()]"/>
</macro>
<inline>
<xsl:call-template name="do_job">
<xsl:with-param name="str" select="."/>
</xsl:call-template>
</inline>
</data>
</xsl:template>
<xsl:template match="myNs:tr">
<xsl:call-template name="do_job">
<xsl:with-param name="str" select="@name"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="do_job">
<xsl:param name="str"/>
<xsl:value-of select="translate($str,'data','DATA')"/>
</xsl:template>
</xsl:stylesheet>
With this input:
<root>
<data>data1</data>
<data>data2</data>
<data>data3</data>
</root>
Output:
<root>
<data>
<macro>DATA1</macro>
<inline>DATA1</inline>
</data>
<data>
<macro>DATA2</macro>
<inline>DATA2</inline>
</data>
<data>
<macro></macro>
<inline>DATA3</inline>
</data>
</root>
Note: Also I recomend to you to read Dimitre Novatchev's FXSL in http://fxsl.sf.net/