2012-05-25 97 views
2

我遇到了麻煩,在尋找一個準確,簡單,回答這個問題的SO或其他地方:XSL處理順序

在XSL文件,你怎麼知道哪個模板將首先處理,第二,等?我讀到它是按XPath的特定順序排列的。另外,XSL 1.0與2.0有區別嗎?

最後,這裏是我正在玩弄的一個有缺陷的XSL文件。目前輸出只是標題「目錄」。我也會在這裏附上XML。

<xsl:template match="/"> 
    <h1> 
     <xsl:text>Table of Contents</xsl:text> 
    </h1> 
</xsl:template> 

<xsl:template match="heading1"> 
    <h2> 
     <xsl:value-of select="."/> 
    </h2> 
</xsl:template> 

<p> 
    <xsl:text>This document contains </xsl:text> 
    <xsl:value-of select="count(/article/body/heading1)"/> 
    <xsl:text> chapters. </xsl:text> 
</p> 

和XML:

<article> 
<title> 
    Creating output 
</title> 
<body> 
    <heading1>Generating text</heading1> 
    <heading1>Numbering things</heading1> 
    <heading1>Formatting numbers</heading1> 
    <heading1>Copying nodes from the input document to the output</heading1> 
    <heading1>Handling whitespace</heading1> 
</body> 

任何解釋爲什麼所有沒有被顯示的內容?感謝您的幫助!

回答

4

這裏發生的事情:

  1. 的XSLT處理器讀取你的XML的根元素
  2. 然後它會在樣式表,看看有什麼相匹配。它找到你的第一個模板
  3. 它執行第一個模板。
  4. 第一個模板表示輸出文本,然後什麼都不做,所以XSLT處理器移動到下一個輸入元素....但是你已經處理了整個根節點,所以沒有更多的輸入節點在同一級別。完成。

您需要做的是在第一個模板中放置一個<xsl:apply-templates/>。當處理器遇到這種情況時,它重新開始,但是這次上下文是根內的第二級節點列表。它會依次查看每個XML節點,在樣式表中找到最匹配的模板並執行它。

這是一個關鍵概念 - 模板不受控制,也不是程序性的。

+0

非常有趣!我忘記了XSLT的性質。在什麼時候我需要使用xsl:apply-templates?當然,我不會在每個深度將它胡椒粉塗抹一遍。 (鑑於一個更大的文件) – BlackVegetable

+2

其實,是的,你這樣做。這種遞歸調用技術被稱爲「推送」處理,因爲您讓XSLT處理器將數據「推送」到您的模板。這是處理器工作的自然方式,所以精心設計的樣式表將與「apply-templates」「拼湊起來」。另一種方法是在「嵌套」for-each和「call-template」的情況下使用「pull」風格,但如果您欣賞拉式處理的力量,那就很不自然。 –

+1

答案的這一點是錯誤的:「所以XSLT處理器移動到下一個輸入元素」。不,它不;它只通過使用xsl:apply-templates進入你要求的地方。 –