2009-09-02 55 views
0

執行可以說我有一個XSLT樣式表如下所示:秩序XSLT樣式表

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exslt="http://exslt.org/common" 
    exclude-result-prefixes="exslt" 
    version="1.0"> 

<xsl:output method="html" encoding="utf-8" indent="no" /> 
<xsl:variable name="foo" value="'foo'" /> 
<xsl:variable name="bar" value="'bar'" /> 

</xsl:stylesheet> 

什麼是執行這裏的秩序?是否保證全局變量$ foo將在全局變量$ bar之前進行計算? (如果它依賴於處理引擎,則使用libxslt)。

回答

3

評價的順序,在一般情況下,不能保證除非這種保證從表達式的依賴關係遵循混日子。例如:

<xsl:variable name="foo" value="123" /> 

<xsl:variable name="bar" value="456" /> 

<xsl:variable name="baz" value="$foo + $bar" /> 

<xsl:variable name="dummy" value="42 div 0" /> 

<xsl:template match="/"> 
    <xsl:value-of select="$baz"/> 
</xsl:template> 

這裏,可以肯定的是baz會在某個時刻被輸出 - 也許之前得到評估僅立即在輸出之前,也許在啓動時,在可能的地方之間 - 這foobar會在baz之前進行評估 - 但foobar的評估的相對順序未定義。

dummy是一個有趣的案例。它並沒有在任何地方實際使用,所以可以完全省略,但是,如果我對規範的理解是正確的,那麼處理器必須提出一個錯誤,就像它被評估一樣。在這一點上,這樣做並不重要,因爲無法從XSLT內部進行分析 - 因此dummy將在執行期間的某個未指定時刻進行評估(可能是第一件事,或者最後所有輸出已經生成) ,但保證會導致轉換失敗並出現錯誤。

這是關於XSLT和XPath 1.0的全部內容。 2。0,它更放鬆 - 評估甚至不需要發生;如果處理器可以通過跳過某些表達式的評估來獲得有效的結果,否則這些表達式會導致錯誤,但它擁有一攬子權限來執行此操作。

+0

謝謝帕維爾。我曾考慮過創建依賴鏈來保證執行順序。然而,由於以下原因,我們的使用案例不切實際: 1.根據'foo'可能會有很多'bar'。讓每個人都依賴'foo'是很繁瑣的。 2.這裏的'foo'和'bar'是由xslt擴展提供的元素/函數。期望擴展的用戶始終指定正確的依賴關係有點容易出錯。 – ajitomatix

+0

爲什麼你需要首先保證任何特定的執行順序?無論如何,您都不應該在XSLT中使用任何帶有副作用的自定義函數,這是唯一可以觀察到差異的情況。如果您需要副作用,XSLT是一個錯誤的選擇。 –

+0

我們需要它,以便我們可以讓用戶設置一些擴展默認設置,然後由擴展中提供的功能使用。是的,我們可以期望用戶必須將這些值作爲參數傳遞給每個函數調用,但這很快就會變得乏味。 – ajitomatix

0

根據我的經驗,變量在模板執行時總是可用的。事實上,我已經根據模板之外的變量處理了模板。

0

在模板的變量定義將在頂部執行到底的順序(foo然後bar

編輯[不正確的語句刪除]:作爲帕維爾解釋here,XSLT已順利在這種情況下,規定如何定義的行爲變量將被評估。特別是,下面的測試用例說明了你所問的行爲。

一個好的測試用例可能是讓一個變量依賴於另一個變量......例如,

<xsl:variable name="foo" select="'foo'" /> 
<xsl:variable name="bar" select="$foo" /> 

那麼也許打印變量屏幕。

的順序可以顛倒,以及(例如)

<xsl:variable name="bar" select="$foo" /> 
<xsl:variable name="foo" select="'foo'" /> 

對於它的價值,我想你的意思select,您在您的文章中寫道value

編輯1: 由於XSLT變量是不變的,因爲執行功能can't have side effects的順序不應該真正的問題。特別是,在我的簡單例子中,訂單至關重要的唯一條件(您應該將其作爲測試運行),其中一個變量取決於另一個變量的值。

編輯2:固定在例如「代碼」

+0

它實際上在XSLT中定義良好;從1.0規範:「如果指定全局變量x的值的模板或表達式引用全局變量y,則y的值必須在x的值之前計算,如果無法執行此操作所有的全局變量定義;換句話說,如果定義是循環的,這是一個錯誤。「 –

+0

謝謝馬克。請參閱我對帕維爾關於爲什麼因變量方法對我不實際的答案的評論。 – ajitomatix

-1

我與ajitomatix正在研究這個問題,真正的問題是:我們有一堆這些變量聲明的任何模板之外,初始化後:

<xsl:variable name="ignore" select="fun_init(args)" /> 
<xsl:variable name="foo1" select="fun('foo1')" /> 
<xsl:variable name="foo2" select="fun('foo2')" /> 
<xsl:variable name="foo3" select="fun('foo3')" /> 
... 

的函數fun()將給只有在確保init函數被調用之前,纔會產生正確的結果。但通過gdb中的斷點,我發現訂單幾乎是隨機的。

+0

感謝您在jdutta78中切入。 – ajitomatix