xsl模版優先級
由 Ghostzhang 發表于 2007-05-12 22:29
當一個節點比對在 XSLT 模闆中建立的多個模式(也稱為規則)時,處理器就會按照 XSLT 規範中描述的沖突解決指導原則來确定使用哪一個模式。這些指導原則表明,當發生沖突時,會調用優先級最高的模闆。然而,确定模闆實際優先級的算法還需要附帶解釋一下。
要确定哪個模闆具有最高優先級,處理器首先會消除導入的所有模闆(使用 xsl:import 元素);自動導入的模闆比經過導入轉換的模闆優先級低。然後處理器确定其餘模闆的優先級值。
可以通過 priority 屬性顯式指定模闆的優先級。例如,以下模闆被賦予優先級 1:
<xsl:template match="/foo/bar" priority="1">
<!-- do something interesting -->
</xsl:template>
複制
如果每個模闆都賦予了優先級,則處理器可以使用這個值來确定哪個模闆具有最高優先級。如果沒有顯式指定優先級,則處理器會為模闆計算一個預設值。由處理器指定的預設優先級範圍是從 -0.5 到 +0.5。基本上,模式越特殊,其預設優先級就越高。由于範圍是從 -0.5 到 +0.5,是以如果顯式指定一個模闆的優先級為 1,就總會超過預設優先級。
Pattern Type | Default Priority | Examples |
---|---|---|
Node test by type | -0.50 | * |
@* | ||
node | ||
comment | ||
text | ||
processing-instruction | ||
Namespace wildcard | -0.25 | ns:* |
QName | 0.00 | foo |
ns:foo | ||
@bar | ||
@ns:bar | ||
Processing instruction tests by literal | 0.00 | processing-instruction('foo') |
Everything else | 0.50 | ns:foo/bar |
ns:foo[@bar] | ||
foo[contains(.,'Aaron')] | ||
//foo | ||
Multiple patterns (pattern1 | pattern2) | Treated as distinct templates, whose priorities are calculated independently |
詳細列出了如何為現有的不同類型的模式指定預設優先級。隻包含按類型的節點測試的模式(例如 *、節點、注釋、文本等)是最一般的,是以它們的預設優先級為 -0.5。隻包含命名空間通配符 (ns:*) 的模式比較具體,是以它們的預設優先級為 -0.25。隻包含限定名測試或常量處理指令測試(例如 foo、ns:foo、@bar、處理指令 (‘foo’) 等等)的模式配置設定的預設優先級為 0。而比這些具體的其他模式所配置設定的預設優先級為 0.5。這意味着具有多個定位步驟 (Location Step),或具有謂詞的任何模式都會自動得到預設優先級 0.5。
仍然存在這樣的情況:有多個具有相同優先級的模闆比對給定的節點。當出現這種情況時,處理器可能産生出錯信号,也可能選擇使用文檔中的最後一個模闆。這是通常的選擇方式。例如,以下 XSLT 片段包含兩個模闆,它們可以比對相同的 foo 元素(該元素具有一個 bar 子元素和一個 bar 父元素)。由于兩個模闆的預設優先級都為 0.5,是以 XSLT 處理器要麼産生出錯信号,要麼選擇文檔中的最後一個模闆 — 在本例中為比對 bar/foo 元素的模闆:
<xsl:template match='foo[bar]' >
<!-- default priority = .5 -->
</xsl:template>
<xsl:template match='bar/foo'>
<!-- default priority = .5 -->
</xsl:template>
複制
當然,您最好是避免出現這樣的情況。如果您想讓處理器在出現沖突時始終使用第一個模闆,則隻需要将它的優先級設為 1,如下面的代碼所示:
<xsl:template match='foo[bar]' priority='1'>
<!-- would have a default priority = .5 -->
</xsl:template>
<xsl:template match='foo/bar' >
<!-- default priority = .5 -->
</xsl:template>
複制
正如您所看到的,當出現沖突時,XSLT 需要經過大量處理才能确定調用哪個模闆。當大量使用 XSLT 的聲明性程式設計模型時,了解這些規則是很有必要的。