【问题标题】:XSL macros - how to create a macro that will replace "call-template" - "with-param" codeXSL 宏 - 如何创建将替换“调用模板”的宏 -“with-param”代码
【发布时间】:2010-08-10 15:55:15
【问题描述】:

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

例如我有以下代码:

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

我想用这样的东西代替:

<myNs:tr name="data1"/>

【问题讨论】:

  • 目前还不清楚您为什么需要这样做。您想使用某种预处理器/代码生成器来创建 XSLT 文件吗? &lt;myNs:tr name="data1" /&gt; 的语义是什么?

标签: xslt macros


【解决方案1】:

无法在 XSLT 中创建和使用宏

在 XSLT 2.0 中,可以使用 &lt;xsl:function&gt; 指令编写函数。然后在任何 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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-18
        • 2016-03-26
        • 1970-01-01
        • 1970-01-01
        • 2017-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多