2014-01-14 127 views
1

我嘗試創建一個變量,我可以在以後的模板中使用:XSLT - 如何使用xsl引用當前節點值:choose?

<xsl:variable name="fc"> 
    <xsl:choose> 
     <xsl:when test="self::node()='element1'">gray</xsl:when> 
     <xsl:otherwise>red</xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 

遺憾的是它不工作。

<xsl:template match="element1"> 
    <h1><font color="{$fc}"><xsl:value-of select="self::node()"/></font></h1> 
</xsl:template> 

我做錯了什麼?

這裏是大量的代碼:

XML:

<root 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com scheme.xsd" xmlns="http://www.test.com" xmlns:tst="http://www.test.com"> 
<elementA> 
    <elementB tst:name="name"> 
     <elementC tst:name="name"> 
      <element1> Test1 </element1> 
      <element2> Test2 </element2> 
     </elementC > 
    </elementB> 
    </elementA>  
</root> 

所有元素都是合格的命名空間 「http://www.test.com」 的一部分。

XSLT:

<xsl:template match="/"> 
<html> 
<body><xsl:apply-templates select="tst:root/tst:elementA/tst:elementB/tst:elementC/tst:element1"/> 
</body> 
</html> 

</xsl:template> 
<xsl:variable name="var_fc"> 
<xsl:choose> 
    <xsl:when test="local-name(.)='tst:element1'">gray</xsl:when> 
    <xsl:otherwise>red</xsl:otherwise> 
</xsl:choose> 
</xsl:variable> 

<xsl:template match="tst:element1"> 
<h2><font color="{$var_fc}"><xsl:value-of select="self::node()"/></font></h2> 
</xsl:template> 

結果,部件1應該變成灰色,但它總是變成紅色。

回答

1

你不能爲此使用變量,因爲xsl:variable的內容在定義時只被計算一次,而你想在每次引用變量時評估一些邏輯,在當前上下文中參考。

相反,你需要一個模板,無論是一個名爲:

<xsl:template name="fc"> 
    <xsl:choose> 
    <xsl:when test="local-name()='element1'">gray</xsl:when> 
    <xsl:otherwise>red</xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

或(更好的)一對與模式匹配模板,讓模板匹配的做的工作:

<!-- match any node whose local name is "element1" --> 
<xsl:template mode="fc" match="node()[local-name() = 'element1']">gray</xsl:template> 

<!-- match any other node --> 
<xsl:template mode="fc" match="node()">red</xsl:template> 

當你想用這樣的邏輯:你有tst前綴地圖

<h1> 
    <font> 
    <xsl:attribute name="color"> 
     <xsl:apply-templates select="." mode="fc" /> 
    </xsl:attribute> 

見此PED在樣式表中,你可以檢查名稱,而不是直接使用local-name()謂詞:

<xsl:template mode="fc" match="tst:element1">gray</xsl:template> 
<xsl:template mode="fc" match="node()">red</xsl:template> 
+0

解決了這個問題,這幫助我很多!謝謝 :) – Ferestes

1

XSLT變量設計爲不可更改的。其實他們可以被命名爲常量。如果你的變量fc是全局創建的,它將使用根元素進行選擇。您必須使用實際模板中的選擇來針對當前元素進行測試。如果您只想定義一次「紅色」和「灰色」,則只需使用該文本內容創建兩個變量,然後在選擇中使用這些變量而不是純文本。

+0

非常感謝!我可以創建兩個變量,但這不是重點。所以沒有測試,可以在全球範圍驗證element1? 當我使用: gray 它總是如此,因爲element1當然存在。 – Ferestes

0

也許這是一個錯字:

<xsl:when test=self::node()='element1'">gray</xsl:when> 

應該是:

<xsl:when test="self::node()='element1'">gray</xsl:when> 

存在丟失的報價。

+0

我改正了它。但是報價不會解決問題 – Ferestes

0

我認爲,而不是test="self::node()='element1'"你想要test="self::element1"test="local-name(.) = 'element1'"

+0

謝謝,但它不起作用 – Ferestes

+0

然後,你將不得不展示一個最小但完整的當前輸入樣本,XSLT,你想要的輸出,然後你現在得到一個。 'test =「self :: element1」'檢查上下文節點是否是名爲'element1'的元素節點。 –

+0

我用原始代碼 – Ferestes

0

一對夫婦在你的代碼的其他錯誤:

(1) self::node() = 'element1' 

測試是否元素的內容是「部件1 「,而不是其名稱是否爲」element1「

(2) local-name(.)='tst:element1' 

永遠不會成立,因爲節點的本地名稱永遠不會包含冒號。

有經驗的用戶會經常使用的模板規則編寫代碼:

<xsl:template mode="var_fc" match="tst:element1">gray</xsl:template> 
<xsl:template mode="var_fc" match="*">red</xsl:template> 

然後

<xsl:apply-templates select="." mode="var_fc"/>