2009-08-27 82 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模板的情況。如果您只想調用一次,那麼只需調用一次。