xml – 在XSLT如何从不同的范围增加一个全局变量?

前端之家收集整理的这篇文章主要介绍了xml – 在XSLT如何从不同的范围增加一个全局变量?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在处理一个XML文件,其中我想保留计数的节点数,以便我可以使用它作为一个ID,因为我写新的节点。

目前我有一个称为“计数器”的全局变量。我可以在模板中访问它,但我还没有找到一种方法在模板中操作它。

这里是我的XSLT文件的精简版本:

<xsl:variable name="counter" select="1" as="xs:integer"/>

<xsl:template match="/"> 
   <xsl:for-each select="section">
      <xsl:call-template name="section"></xsl:call-template>
   </xsl:for-each>
</xsl:template>

<xsl:template name="section">

   <!-- Increment 'counter' here -->

   <span class="title" id="title-{$counter}"><xsl:value-of select="title"/></span>
</xsl:template>

任何建议如何从这里?

其他人已经解释了变量是如何不可变的 – 在XSLT中没有赋值语句(一般与纯函数编程语言一样)。

我有一个替代目前已经提出的解决方案。它避免参数传递(在XSLT中是冗长和丑陋的 – 即使我承认)。

在XPath中,您可以简单地计算< section>在当前元素之前的元素:

<xsl:template name="section">
  <span class="title" id="title-{1 + count(preceding-sibling::section)}">
    <xsl:value-of select="title"/>
  </span>
</xsl:template>

(注意:空格代码格式化不会出现在结果中,因为只有空格的文本节点会自动从样式表中删除,因此不要在同一行上放置说明。)

这种方法的一个很大的优点(相对于使用position()),它只依赖于当前节点,而不是当前节点列表。如果您以某种方式更改了处理(例如,因此< xsl:for-each>不仅处理段而且处理了一些其他元素),那么position()的值不再必须对应于< section>元素。另一方面,如果使用如上所述的count(),则它将总是对应于每个<节>的位置。元件。这种方法减少了与代码的其他部分的耦合,这通常是一件很好的事情。

count()的替代方法是使用< xsl:number>指令。它的默认行为将会编号在同一级别的所有类似命名的元素,这恰恰是你想要的:

<xsl:template name="section">
  <xsl:variable name="count">
    <xsl:number/>
  </xsl:variable>
  <span class="title" id="title-{$count}">
    <xsl:value-of select="title"/>
  </span>
</xsl:template>

这是一个冗余的折衷(如果你仍然想要使用属性值模板花括号,需要一个额外的变量声明),但只是稍微这样,因为它也大大简化了XPath表达式。

还有更多的改进空间。虽然我们已经删除了对当前节点列表的依赖,但是我们仍然依赖于当前节点。这本身并不是一件坏事,但是从模板上看不清楚当前节点是什么。我们所知道的是模板命名为“section”;以确定正在处理什么,我们必须在我们的代码中的其他地方。但即使这不是必须的。

如果你觉得导致使用< xsl:for-each>和< xsl:call-template>一起(如在您的示例中),回退并找出如何使用< xsl:apply-templates>代替。

<xsl:template match="/doc">
  <xsl:apply-templates select="section"/>
</xsl:template>

<xsl:template match="section">
  <xsl:variable name="count">
    <xsl:number/>
  </xsl:variable>
  <span class="title" id="title-{$count}">
    <xsl:value-of select="title"/>
  </span>
</xsl:template>

这种方法不仅减少了冗余(< xsl:apply-templates />替换了< xsl:for-each>和< xsl:call-template />),节点是。您只需查看match属性即可知道您正在处理< section>元素和<节>元素是你计数。

有关如何工作的模板规则(即< xsl:template>元素具有匹配属性)的简要说明,请参见“How XSLT Works”

猜你在找的XML相关文章