2009-01-26 91 views
12

有沒有辦法編寫一個在所有模式下匹配的XSL 1.0模板?XSL模板可以匹配* ALL *模式嗎?

或者我必須爲每個現有模式(包括未來添加模式的其他模板)編寫一個單獨的模板嗎?

以下是我有:

<xsl:apply-templates mode="mode1" /> 
    ... 
<xsl:apply-templates mode="mode2" /> 
    ... 
<!-- Do not process text content of nodes no matter in what mode --> 
<!-- Is there a way to have only one template here? --> 
<xsl:template match="text()" mode="mode1" /> 
<xsl:template match="text()" mode="mode2" /> 
+0

@divo我不會推薦任何人在XSLT 2.0中使用#all - 這太危險了。例如,一個更通用的模板(匹配節點())會干擾*任何其他*模板。更好的辦法是更仔細地設計一個模板,以更清晰的方式,這樣就不需要#all。 – 2009-01-26 20:22:28

+0

@divo如果使用而不是使用 2009-01-26 22:44:34

+0

@Dimitre:是的,當然你是對的。但是,您的解決方案意味着修改代碼中的每個應用程序模板,這使得維護非常困難,並且似乎對我來說很容易出錯。 – 2009-01-27 15:51:10

回答

7

預定義模式:#all(僅在XSLT 2.0然而可用)。

編輯:1.0

<xsl:template match="/"> 
    <xsl:variable name="choice" select="'a'"/><!-- input seed here --> 
    <xsl:choose> 
     <xsl:when test="$choice='a'"> 
      <xsl:apply-templates mode="a"/> 
     </xsl:when> 
     <xsl:when test="$choice='b'"> 
      <xsl:apply-templates mode="b"/> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="*" mode="a"> 
    [A] 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="*" mode="b"> 
    [B] 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="text()"> 
    [ALL] 
</xsl:template> 
+0

這真的很棒!謝謝你的答案,但它似乎只有XSLT 2.0,我忘了提及我被限制使用XSLT 1.0 :-(看來我將不得不編寫一個單獨的模板... – 2009-01-26 12:29:42

1

如果你想在所有的模式,然後你爲什麼使用模式的模板匹配中的共享模式的行爲嗎?如果你不使用模式,模板將一直使用。模式的原因是有條件地用相同的數據類型做不同的事情。似乎你想要無模式。

2

有沒有寫這是在所有 模式

是相匹配的XSL 1.0 模板的方式,才能做到這一點應該遵循以下兩條規則

  1. 編寫模板沒有模式屬性

  2. 內moded模板具有<xsl:apply-templates>指令未經模式屬性,這將導致在模板上面1被選擇用於處理

這直接從XSLT 1.0屬,which says如下

如果一個xsl:apply-templates元素有 a mode屬性,則它僅適用於 到那些具有相同值的mode 屬性的元素 xsl:template;如果 xsl:apply-templates元素不 有mode屬性,那麼它適用 只從 xsl:template元素的模板規則沒有 一個mode屬性。

總結:一組中的每個模板在不同的模式以這樣的方式(上述)仍然可以發出<xsl:apply-templates>,使得相同的特異性的,單模板將在每種情況下被選擇用於處理。