2015-01-05 34 views
1

我有一個XML文件看起來像下面是什麼目的的<xsl:調用模板...>

- <select1> 
    - <sel_details> 
     <type>Primary Type</type> 
     <name>Some Name</name> 
     <id>ID Num</id> 
    <sel_details> 
    ..... 
    <select1> 

和XSL看起來像這樣

<xsl:for-each select="//select1"> 
    <xsl:call-template name="sel_details" /> 
    <xsl:with-param name="xmlSection" select="sel_details" /> 
    </xsl:call-template> 
    <xsl:call-template name="....." /> 
    <xsl:with-param name="xmlSection" select="....." /> 
    </xsl:call-template> 
    .......... 
</xsl:for-each> 

<xsl:template name="sel_details"> 
    <xsl:param name="xmlSection" /> 
     <xsl:for-each select="xmlSection"> 
      <xsl:value-of select="./type" /> 
     </xsl:for-each> 
</xsl:template> 

是什麼目的<xsl:call-template...>然後<xsl:template name...>

如果我只寫3這樣的線,我能得到相同的值:在一個普通的編程語言

<xsl:for-each select="//select1/sel_details"> 
    <xsl:value-of select="./type" /> 
</xsl:for-each> 

回答

1

什麼是命名模板?

在XSLT樣式表中,xsl:call-template

<xsl:call-template name="construct-header"/> 

意味着調用所謂命名模板 - 具有name屬性的xsl:template元件:

<xsl:template name="construct-header"> 

作爲相對於一個匹配輸入節點的模板,因此具有match屬性:

<xsl:template match="book"> 

由於命名模板從不匹配到輸入節點,所以使用xsl:call-template顯式調用它們是執行它們內部代碼的唯一方法。一旦命名模板被調用,代碼將被評估,不會改變上下文(broadly speaking, at least)。所以,一個非常合理的問題是

爲什麼在一般情況下使用命名模板?

命名模板用於

  • 實現在XSLT遞歸算法。一個衆所周知的例子是mimicking the tokenize() function in XSLT 1.0,它需要一個遞歸的命名模板。
  • 重用幾個地方的代碼塊以避免重複
  • 將樣式表組織成有意義的部分。這也可以通過模塊化您的代碼到由主樣式表包含或導入的幾個樣式表中。

使用您的具體情況

命名模板如果代碼是爲你展示真正的短,我看不出有什麼理由在這裏使用一個命名模板。在命名模板中沒有遞歸處理。但是也許在發佈之前大大縮短了它,或者在樣式表的其他地方重新使用了已命名的模板。這兩個都是保持命名模板的合理原因。 (如果您想在這個明確的指導,請出示一個完整的樣式表。)

如果你決定代碼降低到xsl:for-each,然後又擺脫./,因爲它是多餘的,而且,從經驗上講,我說,不應該在路徑表達式前面是//

<xsl:for-each select="select1/sel_details"> 
    <xsl:value-of select="type" /> 
</xsl:for-each> 
+0

非常感謝MathiasMüller!你的解釋非常清楚直接! –

+0

嗨Mathias,關於你提到的'在幾個地方重複使用代碼塊以避免重複',並且我也閱讀了你提供的鏈接(至少廣義而言),這是一個很好的問題和答案。非常感謝!我也有同樣的擔憂:例如,我聲明瞭模板名稱A,並選擇了顯示在頁面頂部的值。然後,在頁面結尾處,模板A的值必須再次顯示,我試着''它不像預期的那樣工作!我收到一個錯誤:「無法將#STRING轉換爲NodeList」如何讓它工作?請指導。謝謝! –

+0

@abcidd評論部分不是提出一個新的,無關的問題的地方。開始一個新的問題帖子來做到這一點。然後我很高興回答 - 或者別人會。但是請確保從頭開始包含以下信息:完整的輸入XML文檔,完整的XSLT樣式表,錯誤描述和您希望擁有的XML輸出。 –

0

想想命名的功能。 <xsl:call-template>是函數調用的直接類比。是否值得將某段代碼移動到單獨的函數中 - 這是編碼風格,代碼重複次數和其他「模糊」考慮的問題。在這個特定的情況下,作者可能希望確保每個部分都將被統一化。也許,在之前的文件修訂中,函數的主體並不重要。

+0

非常感謝,user3159253!從你的話來說,我已經瞭解了更多關於XSL的知識。謝謝! –

1

代碼看起來對我來說,就好像它是由人誰還沒掌握XSLT的應用模板的成語。我想象一個更有經驗的XSLT程序員可能會寫這樣的事情:

<xsl:template match="/"> 
    ... 
    <xsl:apply-templates select="//select1"/> 
    ... 
</xsl:template> 

<xsl:template match="select1"> 
    <xsl:apply-templates select="sel_details" /> 
    <xsl:apply-templates select="....." /> 
</xsl:template> 

<xsl:template match="sel_details"> 
    <xsl:value-of select="type" /> 
</xsl:template> 

樣式表中的xsl:for-each和xsl:調用模板和xsl:選擇是主要的控制結構一般建議程序員是誰對XSLT習語尚不熟悉。有經驗的XSLT編碼人員使用匹配模板和xsl:apply-templates。

+0

非常感謝Mike Kay!這是對的,我不是XSL的主人,是的,我不知道'匹配'!非常感謝您分享經驗!不勝感激。 –