共用方式為


路徑運算式 - 指定節點測試

適用於:SQL Server

路徑運算式中的軸步驟包含下列元件:

如需詳細資訊,請參閱 路徑表示式 (XQuery)

節點測試是條件,而且是路徑表達式中座標軸步驟的第二個元件。 步驟所選取的所有節點都必須滿足此條件。 對於路徑表示式, /child::ProductDescription節點測試為 ProductDescription。 此步驟只會擷取名稱為 ProductDescription 的元素節點子系。

節點測試條件可以包含下列專案:

  • 節點名稱。 只會傳回具有指定名稱之主體節點種類的節點。

  • 節點類型。 只會傳回指定類型的節點。

注意

XQuery 路徑表示式中指定的節點名稱不會受限於與 Transact-SQL 查詢相同的定序敏感性規則,而且一律會區分大小寫。

節點名稱做為節點測試

在路徑表達式步驟中將節點名稱指定為節點測試時,您必須瞭解主體節點種類的概念。 每個座標軸、子系、父系或屬性都有主體節點種類。 例如:

  • 屬性軸只能包含屬性。 因此,屬性節點是屬性座標軸的主要節點種類。

  • 對於其他座標軸,如果座標軸所選取的節點可以包含元素節點,元素就是該座標軸的主要節點種類。

當您將節點名稱指定為節點測試時,步驟會傳回下列類型的節點:

  • 屬於座標軸上主節點類型的節點。

  • 節點測試中具有相同名稱的節點。

例如,請考慮下列路徑表示式:

child::ProductDescription   

這個單步驟表達式會將 child 座標軸和節點名稱 ProductDescription 指定為節點測試。 表達式只會傳回子軸、項目節點以及 ProductDescription 為其名稱之主體節點類型的節點。

路徑表達式 /child::PD:ProductDescription/child::PD:Features/descendant::*, 有三個步驟。 這些步驟會指定子軸和子系座標軸。 在每個步驟中,節點名稱都會指定為節點測試。 第三個步驟中的通配符 (*) 表示子系座標軸之主體節點種類的所有節點。 座標軸的主要節點種類會決定選取的節點類型,而節點名稱會篩選選取的節點。

因此,當此表達式針對 ProductModel 數據表中的>

路徑表達式 /child::PD:ProductDescription/attribute::ProductModelID是由兩個步驟所組成。 這兩個步驟都會將節點名稱指定為節點測試。 此外,第二個步驟會使用屬性軸。 因此,每個步驟都會選取其座標軸之主體節點類型的節點,其名稱指定為節點測試。 因此,表達式會傳> 屬性節點。

指定節點測試的節點名稱時,您也可以使用通配符 「,」 來指定節點的本機名稱或其命名空間前置詞,如下列範例所示:

declare @x xml  
set @x = '  
<greeting xmlns="ns1">  
   <salutation>hello</salutation>  
</greeting>  
<greeting xmlns="ns2">  
   <salutation>welcome</salutation>  
</greeting>  
<farewell xmlns="ns1" />'  
select @x.query('//*:greeting')  
select @x.query('declare namespace ns="ns1"; /ns:*')  

節點類型做為節點測試

若要查詢項目節點以外的節點類型,請使用節點類型測試。 如下表所示,有四個節點類型測試可供使用。

節點類型 傳回 範例
comment() 如果是批注節點,則為 True。 following::comment() 會選取內容節點之後出現的所有批注節點。
node() True 是表示 任何種類的節點。 preceding::node() 會選取出現在內容節點之前的所有節點。
processing-instruction() 如果是處理指令節點,則為 True。 self::processing instruction() 會選取內容節點內的所有處理指令節點。
text() True 是表示 文字節點。 child::text() 會選取內容節點子系的文字節點。

如果節點類型,例如 text() 或 comment() ...,指定為節點測試,則步驟只會傳回指定類型的節點,而不論座標軸的主要節點種類為何。 例如,下列路徑表示式只會傳回內容節點的批註節點子系:

child::comment()  

同樣地,/child::ProductDescription/child::Features/child::comment()擷取 ProductDescription< 元素節點節點之 Features> 元素節點子系的<批注>節點子系。

範例

下列範例會比較節點名稱和節點種類。

A. 將節點名稱和節點類型指定為路徑表示式中的節點測試的結果

在下列範例中,會將簡單的 XML 檔指派給 xml 類型變數。 使用不同的路徑表達式來查詢檔。 然後會比較結果。

declare @x xml  
set @x='  
<a>  
 <b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
 </b>  
</a>'  
select @x.query('  
/child::a/child::b/descendant::*  
')  

此表達式會要求元素節點的 <b> 子代項目節點。

節點測試中的星號 (*) 表示節點名稱的通配符。 子系座標軸具有項目節點做為其主要節點種類。 因此,表達式會傳回項目節點 的所有子代項目節點 <b>。 也就是說,會傳回元素節點 <c><d> ,如下列結果所示:

<c>text2  
     <d>text3</d>  
</c>  
<d>text3</d>  

如果您指定子系或自我軸,而不是指定子系座標軸,則會傳回內容節點,以及其子系:

/child::a/child::b/descendant-or-self::*  

此表達式會傳回項目節點 <b> 及其子代項目節點。 在傳回子代節點時,子代或自我座標軸的主要節點種類,元素節點類型會決定傳回的節點類型。

以下是結果:

<b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
</b>  
  
<c>text2  
     <d>text3</d>  
</c>  
  
<d>text3</d>   

上一個表達式使用通配符做為節點名稱。 相反地,您可以使用 函 node() 式,如下列表達式所示:

/child::a/child::b/descendant::node()  

因為 node() 是節點類型,因此您會收到子代座標軸的所有節點。 以下是結果:

text1  
<c>text2  
     <d>text3</d>  
</c>  
text2  
<d>text3</d>  
text3  

同樣地,如果您將子系或自我軸 node() 指定為節點測試,您會收到所有子代、元素和文字節點,以及內容節點、 <b> 元素。

<b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
</b>  
text1  
<c>text2  
     <d>text3</d>  
</c>  
text2  
<d>text3</d>  
text3  

B. 在節點測試中指定節點名稱

下列範例會將節點名稱指定為所有路徑表示式中的節點測試。 因此,所有表達式都會傳回節點類型之座標軸之節點的節點,這些節點名稱在節點測試中指定。

下列查詢表示式會 <Warranty> 從儲存在資料表中的 Production.ProductModel 產品目錄 XML 檔案傳回 元素:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::wm:Warranty  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

請注意下列項目是從上一個查詢而來:

  • namespace XQuery 初構中的 關鍵詞會定義用於查詢主體的前置詞。 如需 XQuery 初構的詳細資訊,請參閱 XQuery Prolog

  • 路徑表達式中的所有三個步驟都會將子軸和節點名稱指定為節點測試。

  • 座標軸步驟的選擇性步驟限定符部分未在表達式中的任何步驟中指定。

查詢會傳<Warranty><Features>回 專案子系的項目子<ProductDescription>系。

以下是結果:

<wm:Warranty xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">  
  <wm:WarrantyPeriod>3 years</wm:WarrantyPeriod>  
  <wm:Description>parts and labor</wm:Description>  
</wm:Warranty>     

在下列查詢中,路徑表達式會在節點測試中指定通配符 (*)。

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::*  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

為節點名稱指定通配符。 因此,查詢會傳回專案節點子節點的所有項目節點 <Features> 子 <ProductDescription> 系。

下列查詢與上一個查詢類似,但與通配符一起指定命名空間。 因此,會傳回該命名空間中的所有項目節點子系。 請注意,元素 <Features> 可以包含來自不同命名空間的專案。

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::wm:*  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

您可以使用通配符作為命名空間前置詞,如下列查詢所示:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::*:Maintenance  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

此查詢會 <Maintenance> 從產品目錄 XML 檔傳回所有命名空間中的項目節點子系。

C. 在節點測試中指定節點種類

下列範例會將節點種類指定為所有路徑表示式中的節點測試。 因此,所有表達式都會傳回節點測試中指定的類型節點。

在下列查詢中,路徑表達式會在其第三個步驟中指定節點種類:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::text()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

在下一個查詢中,指定下列專案:

  • 路徑表達式有三個步驟,以斜線標記 (/) 分隔。

  • 每個步驟都會指定子軸。

  • 前兩個步驟會將節點名稱指定為節點測試,而第三個步驟則指定節點種類做為節點測試。

  • 表達式會傳回項目節點之專案子系的<Features>文字節點<ProductDescription>子系。

只會傳回一個文字節點。 以下是結果:

These are the product highlights.   

下列查詢會傳回 專案的批註節點子 <ProductDescription> 系:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::comment()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

請注意下列項目是從上一個查詢而來:

  • 第二個步驟會將節點種類指定為節點測試。

  • 因此,表達式會傳回項目節點的 <ProductDescription> 批註節點子系。

以下是結果:

<!-- add one or more of these elements... one for each specific product in this product model -->  
<!-- add any tags in <specifications> -->      

下列查詢會擷取最上層的處理指令節點:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::processing-instruction()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

以下是結果:

<?xml-stylesheet href="ProductDescription.xsl" type="text/xsl"?>   

您可以將字串常值參數傳遞至 processing-instruction() 節點測試。 在此情況下,查詢會傳回處理指令,其名稱屬性值是 自變數中指定的字串常值。

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::processing-instruction("xml-stylesheet")  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

實作限制

以下是特定限制

  • 不支援擴充的 SequenceType 節點測試。

  • 不支援 processing-instruction(name)。 請改用引號括住名稱。