在xslt中将局部变量从一个模板传递到另一个模板

时间:2018-06-12 07:06:30

标签: xml xslt xslt-1.0 xslt-2.0

我需要将一个模板中定义的局部变量的值传递给另一个模板 模板。

以下源不起作用(即我无法将局部变量传递给另一个模板)。怎么了 ?非常感谢。

   `        <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="text"/>

      <xsl:template match="/">
        <xsl:apply-templates select="A/B/C">
        </xsl:apply-templates>
        <xsl:apply-templates select="A/B/D/E/F">
          <xsl:with-param name="XYZ" select="$XYZ" >
          </xsl:with-param>
        </xsl:apply-templates>
      </xsl:template>

      <xsl:template match="A/B/C">
        <xsl:variable name="XYZ">
          <xsl:value-of select="K/L/M/N/O"/>
        </xsl:variable>
      </xsl:template>

      <xsl:template match="A/B/D/E/F">
        <xsl:text>BLAH-BLAH-BLAH-111</xsl:text>
        <xsl:value-of select="$XYZ" />
        <xsl:text>BLAH-BLAH-BLAH-999</xsl:text>
      </xsl:template>
    </xsl:stylesheet>`

2 个答案:

答案 0 :(得分:2)

您需要在匹配模板中使用xsl:param声明参数

<xsl:template match="A/B/D/E/F">
    <xsl:param name="XYZ" />
    <xsl:text>BLAH-BLAH-BLAH-111</xsl:text>
    <xsl:value-of select="$XYZ" />
    <xsl:text>BLAH-BLAH-BLAH-999</xsl:text>
  </xsl:template>

但是,选择此模板的代码块存在问题

 <xsl:apply-templates select="A/B/D/E/F">
    <xsl:with-param name="XYZ" select="$XYZ" >
 </xsl:with-param>

xsl:with-param正在选择要作为参数传递的变量名XYZ,但该变量在模板中不存在。也许您希望它使用模板匹配中定义的变量&#34; A / B / C&#34;?这不会发生,因为变量在声明它们的块的范围内是本地的。

也许您需要像这样编写XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:variable name="XYZ">
      <xsl:apply-templates select="A/B/C" />
    </xsl:variable>
    <xsl:apply-templates select="A/B/D/E/F">
      <xsl:with-param name="XYZ" select="$XYZ" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="A/B/C">
      <xsl:value-of select="K/L/M/N/O"/>
  </xsl:template>

  <xsl:template match="A/B/D/E/F">
    <xsl:param name="XYZ" />
    <xsl:text>BLAH-BLAH-BLAH-111</xsl:text>
    <xsl:value-of select="$XYZ" />
    <xsl:text>BLAH-BLAH-BLAH-999</xsl:text>
  </xsl:template>
</xsl:stylesheet>

将其应用于此XML

<A>
  <B>
    <C>
      <K>
        <L>
          <M>
            <N>
              <O> *** Parameter *** </O>
            </N>
          </M>
        </L>
      </K>
    </C>
    <D>
      <E>
        <F>Test</F>
      </E>
    </D>
  </B>
</A>

以下是输出

BLAH-BLAH-BLAH-111 *** Parameter *** BLAH-BLAH-BLAH-999

答案 1 :(得分:1)

您的非工作代码似乎是:

  • A致电B
  • B设置局部变量$ XYZ
  • A来电C
  • 您希望C有权访问$ XYZ

问题不在于将参数从A传递给C:这很容易。问题是将$ XYZ的值从B返回给其调用者A.

执行此操作的方式取决于您使用的XSLT版本。

  • 在XSLT 1.0中,您可以从模板返回的唯一内容是一大块XML。模板B需要在XML片段中包含它想要返回的所有内容,模板A需要在变量中捕获该XML片段。为了有用,它需要exslt:node-set()扩展来将XML片段转换为节点集,从中可以提取所需的部分。

  • 在XSLT 2.0中,另一个选项是从模板返回一系列事物(例如XML节点):例如,调用者可以将该序列中的第一个项目复制到转换结果,并且将序列中的第二项传递给另一个模板以进行进一步处理。

  • 在XSLT 3.0中,您可以使用地图而不是序列,因此结果中的不同内容通过名称而不是位置来标识。

所有这些都是非常干燥和学术性的。如果您确实告诉我们您的转换正在尝试做什么(输入是什么,输出是什么以及它们如何相关?),我们可以给您一个更好的答案。也许关于传递参数的所有这些东西意味着你以错误的方式开展工作,并且你会采用完全不同的方法做得更好。