2009-08-27 85 views
6

我有一个可以在整个转换过程中多次应用的XSLT块。但是我希望它只在第一次应用时才运行,所有时间都会跳过它。我该怎么做呢?在XSLT中,我只能运行一次模板吗?

作为一个例子,这是诸如此类的事情,我想做的事: 在样式表我定义一个全局变量:

<xsl:variable name="run_once" select="0"/> 

然后我就被称为模板几次:

<xsl:template name="some_template"> 
    <xsl:if test="$run_once != 1"> 
     <xsl:variable name="run_once" select="1"/> 
     <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text> 
    </xsl:if> 
</xsl:template> 

这当然不起作用,因为变量不能改变,只能重载。因此,一旦some_template退出$ run_once再次为0,并且每次调用模板时都会应用文本。 是否有某种类型的ifdef功能或其他可以设置的全局对象?

如果你有兴趣,为什么我要做到这一点,下面是我的问题的更详细的解释,我用的解决方案:

  • 我输入的是原始的XML数据,我 输出是以WordML格式报告。
  • 在输入中,我有一系列节点 (名为theNode)。有些但不是 全部,这些节点需要在输出中显示 。只有当XPath hairyLogic为真(毛发逻辑明显长并且 复杂)时,才应该显示节点 。
  • theNode's也有类型(存储在 的子节点)。在输入中,所有 相同类型的节点将始终分组在一起。在 输出中,所有类型相同的 的节点应归入该类型的 特定标题下(对于每个 类型, 应该只有一个标题)。

这是我最终使用的解决方案:

... 
<xsl:apply-templates select="theNode[hairyLogic]"/> 
... 

<xsl:template match="theNode"> 
    <xsl:if test="count(preceding-sibling::theNode[type = current()/type and hairyLogic])=0"> 
     <xsl:choose> 
      <xsl:when test="type = 'TYPE1a' or type = 'TYPE1b'"> 
       <xsl:call-template name="TYPE1Heading"/> 
      </xsl:when> 
      <xsl:when test="type = 'TYPE2'"> 
       <xsl:call-template name="TYPE2Heading"/> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:if> 
    ... 
</xsl:template> 

我选择使用命名模板的标题,因为它们含有不依赖于XML输入任何数据基本的WordML。

我不喜欢这个解决方案,因为hairyLogic被重复,if语句错综复杂,难以阅读。也许你有更好的解决方案,不需要可变变量?

回答

2

我建议在命名模板上使用匹配模板,因为它更多,是什么XSLT等效于pythonic? XSLT-Y?我认为你会发现你可以在这种处理方法中更容易地解决问题。

如果你坚持使用,因为一些未知的要求命名模板,你可能会发现,如果你重构你的逻辑,可以很容易地检测到第一个实例,你就会完全简化你的逻辑。

你能澄清,为什么需要在第一种情况下,当你无法察觉?我们可以帮助制作一个xpath表达式,它可以让你确实想要。例如。

<xsl:template name="some_template"> 
    <xsl:variable name="EXPRESSION" select=".[somelogic='true']"/> 
    <xsl:if test="$EXPRESSION"> 
     <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text> 
    </xsl:if> 
</xsl:template> 

由于XSLT是确定的 - (除非你做怪异的扩展的东西)在第一时间通过应用逻辑输入适当的你可以决定 - 被完全功能格雷戈把它的作用。另外,您可以访问模板中的上下文节点,以便知道它从哪里被调用。

+0

“什么是Python化的XSLT equivilent?XSLT-Y?” - 这是“声明” – 2009-09-01 17:40:43

+0

是的,我有限制,我并没有完全细节(加入到这个问题,如果你有兴趣)。我用你描述的方式解决了问题。我不喜欢它,因为“somelogic”很长,很杂乱,现在重复了好几次。它不会如此糟糕,如果当XPATH代码解析我能决定,就像我可以在其他功能的语言。然后,我可以将“somelogic”的坏点存储在变量中,并在需要时将其插入到我的表达式中。 – oillio 2009-09-17 01:38:32

2

因为XSLT是一个纯粹的功能性语言,有可以设置不全局变量。

您将不得不选择您致电some_template模板的情况。如果您只想调用一次,那么只需调用一次。