2010-05-14 93 views
7

我相信這是一個非常基本的問題,但無論如何,這裏仍然存在!我已閱讀,內置的模板規則文本和XSLT屬性節點是XSLT內置模板屬性規則

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

但是源文檔

<?xml version="1.0"?> 
<booker> 
<award> 
    <author blah="test">Aravind Adiga</author> 
    <title>The White Tiger</title> 
    <year>2008</year> 
</award> 
</booker> 

和XSLT

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
</xsl:stylesheet> 

我得到以下輸出在Visual Studio中應用轉換。有人能解釋爲什麼我在輸出中看不到「測試」嗎?

阿拉文·阿迪加

白虎

回答

6

由於對要素內置的規則並不模板應用到元素自身的屬性,只有它的子元素。如果你想以同樣的方式來遍歷屬性您遍歷子元素(這可能是一個人工任務),你需要定義自己的默認:

<xsl:template match="*"> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates/> 
</xsl:template> 
+1

我同意,只是爲了增加完整性 - 默認的''選擇所有的子節點,不僅僅是元素(否則沒有什麼會被代碼從問題中輸出)。 – Krab 2010-05-14 16:06:00

+0

謝謝,我不需要真的這樣做,我只是想了解規則。所以基本上,內建規則的「@ *」部分將永遠不會被調用,除非它被明確調用? – 2010-05-14 16:10:01

6

要評論解決這個問題:

謝謝,我不需要真的去做,我只是想了解規則。所以基本上,內置規則的@ *部分將永遠不會被調用,除非它被明確調用?

在這種情況下,有利息我們兩個默認的規則:

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

<xsl:template match="/|*"> 
    <xsl:apply-templates/> 
</xsl:template> 

當文檔被處理時,第二個模板根匹配並應用模板。 apply-templates的默認值是選擇所有的子節點(屬性,容易混淆,不是子節點)。您從不選擇任何要處理的屬性,因爲唯一的apply-templates以其默認形式出現。

所以如果你選擇了某個地方的任何屬性(如Vincent Marchetti所做的),它將由第一個提到的默認模板進行處理。

+0

+1我看到了!感謝這一切現在是有道理的。 – 2010-05-14 16:20:07

2

主要規則是 - 屬性根本沒有標識 - 它們只能作爲連接到節點的橫向位來訪問。在您首先創建節點之前,將它們視爲不存在是很好的。您也可以將它們視爲XPath和XSLT世界中的完全二等公民。每次在選擇條件中使用它們就像在SQL中從一個連接切換到一個遊標,並且每次使用「for」而不是「apply」時,都會發生同樣的情況。

另一種方式來說 - 你唯一真正有效的「索引」是在文檔中包含所有XPath的。(.Net實際上構建了XPaths的Hashtable =>常量時間匹配)。 「應用」是有特權的原因是它保證了純粹的功能處理 - 你可以運行匹配的所有東西,通過適用於單獨的線程而不需要同步,也不需要共享內存 - 你只需要連接它們的結果。

第三種方式來看看它,這是一個延伸,想象你的標籤是SQL表,並且只有代理PK-s和FK-s - 除了「全部來自T1和全部與T2相關「。對於任何體面的SQL引擎來說,它就像是一個零成本的工作 - 它只是逐條地讀取一個好的索引,因爲它的結構在查詢時爲1-1。其他一切花費更多。

一旦你選擇了標籤並且模板匹配並運行,那麼只要獲取屬性的值就很便宜 - 只要你轉換/渲染它們即可。 XPath結束時的屬性測試也相當便宜 - 同樣,因爲最終的標籤/節點已被選中,現在它只是一個小小的過濾器。

所以,XSLT引擎和XPath選擇一般都有很好的理由完全忽略attributes - perf。