XSL宏 - 如何创建一个将替换“call-template” - “with-param”代码的宏

时间:2010-08-10 15:55:16

标签: xslt macros

我正在尝试找到一种解决方案,用于替换“call-template”类型的标准3行代码 - “with-param”,只需一行。

例如,我有以下代码:

<xsl:call-template name="do_job">
    <xsl:with-param name="str">data1</xsl:with-param>
</xsl:call-template>

我想用这样的东西替换:

<myNs:tr name="data1"/>

3 个答案:

答案 0 :(得分:3)

无法在XSLT中创建和使用宏

在XSLT 2.0中,可以使用<xsl:function>指令编写函数。然后在任何XPath表达式中引用函数:

my:do_job(someString)

以下是完整示例

<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>

将此转换应用于任何XML文档(未使用)时,会生成正确的结果

13

答案 1 :(得分:1)

正如Dimitre所说,不支持宏。但是,您可以从包含宏的XML文档中动态生成XSLT,然后运行生成的XSLT。

创建XSLT的样式表如下所示:

<xsl:template match="myNs:tr">
    <xsl:call-template name="do_job">
        <xsl:with-param name="str" select="{@name}" />
    </xsl:call-template>
</xsl:template>

答案 2 :(得分:0)

除了Dimitre出色的答案和推荐,你可以像这样的样式表:

<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>

使用此输入:

<root>
    <data>data1</data>
    <data>data2</data>
    <data>data3</data>
</root>

输出:

<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>

注意:我还建议您在http://fxsl.sf.net/

中阅读Dimitre Novatchev的FXSL