次の方法で共有


パス式 - ノード テストの指定

適用対象: SQL Server

パス式の軸ステップには、次のコンポーネントが含まれます。

詳細については、「 Path 式 (XQuery)」を参照してください。

ノード テストは条件であり、パス式の軸ステップの 2 番目のコンポーネントです。 ステップで選択したすべてのノードは、この条件を満たす必要があります。 パス式 /child::ProductDescription の場合、ノード テストは ProductDescription です。 この手順では、ProductDescription という名前の要素ノードの子のみを取得します。

ノード テストの条件には、次の情報を含めることができます。

  • ノード名。 指定した名前を持つ、主ノード種別に属するノードのみが返されます。

  • ノードの種類。 指定した型のノードのみが返されます。

Note

XQuery パス式で指定されたノード名は、Transact-SQL クエリと同じ照合順序に依存する規則の対象ではなく、常に大文字と小文字が区別されます。

ノード テストとしてのノード名

パス式のステップでノード名をノード テストとして指定する場合は、主ノード種別の概念を理解しておく必要があります。 すべての軸、子、親、または属性には、プリンシパル ノードの種類があります。 次に例を示します。

  • attribute 軸には、属性のみを含めることができます。 したがって、属性ノードが attribute 軸の主ノード種別になります。

  • その他の軸の場合、軸で選択されるノードに要素ノードを含めることができる場合は、要素がその軸の主ノード種別になります。

ノード名をノード テストとして指定すると、ステップから次の型のノードが返されます。

  • 軸の主ノードの種類を持つノード。

  • ノード テストに指定したのと同じ名前のノード。

たとえば、次のパス式を考えてみましょう。

child::ProductDescription   

この 1 ステップの式では、child 軸とそのノード名 ProductDescription をノード テストとして指定しています。 式は、子軸、要素ノードのプリンシパル ノードの種類であり、名前として ProductDescription を持つノードのみを返します。

パス式 /child::PD:ProductDescription/child::PD:Features/descendant::*, には、3 つのステップがあります。 これらのステップでは、child 軸と descendant 軸を指定しています。 各ステップでは、ノード名がノード テストとして指定されます。 3 番目のステップのワイルドカード文字 (*) は、子孫軸の原則ノードの種類のすべてのノードを示します。 軸の主要ノードの種類によって、選択したノードの種類が決まります。ノード名は、選択したノードをフィルター処理します。

その結果、ProductModel テーブル内の製品カタログ XML ドキュメントに対してこの式が実行されると、<ProductDescription> 要素の<Features>要素ノードの子のすべての要素ノードの子が取得されます。

パス式 /child::PD:ProductDescription/attribute::ProductModelIDは、2 つのステップで構成されます。 どちらのステップでも、ノード名をノード テストとして指定しています。 また、2 番目の手順では属性軸を使用します。 そのため、各ステップでは、ノード テストとして指定された名前を持つ軸のプリンシパル ノードの種類のノードが選択されます。 したがって、この式は、<ProductDescription> 要素ノードの 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:*')  

ノード テストとしてのノード型

要素ノード以外のノードタイプを照会するには、ノードタイプテストを使用します。 次の表に示すように、4 つのノード タイプ テストを使用できます。

ノードの種類 返品
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> 要素ノードの子孫にあたる要素ノードが要求されます。

ノード テストのアスタリスク (*) は、ノード名のワイルドカード文字を示しています。 descendant 軸の主ノード種別は要素ノードです。 したがって、式は要素ノード <b>のすべての子孫要素ノードを返します。 つまり、次の結果に示すように、要素ノード <c><d> が返されます。

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

次のように、descendant 軸ではなく descendent-or-self 軸を指定すると、コンテキスト ノードとその子孫が返されます。

/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  

さらに、descendant-or-self 軸と node() をノード テストに指定した場合は、すべての子孫、要素、テキスト ノード、およびコンテキスト ノードである <b> 要素が返されます。

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

B. ノード テストでのノード名の指定

次の例では、すべてのパス式でノード名をノード テストとして指定します。 結果として、すべての式により、ノード テストに指定したノード名を持つ、軸の主ノード種別に属するノードが返されます。

次のクエリ式は、Production.ProductModel テーブルに格納されている製品カタログ XML ドキュメントの<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::wm:Warranty  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

上のクエリに関して、次の点に注意してください。

  • XQuery プロローグ内の namespace キーワードにより、クエリ本文で使用するプレフィックスが定義されています。 XQuery プロローグの詳細については、 XQuery Prolog を参照してください。

  • パス式の 3 つのステップはすべて、ノード テストとして子軸とノード名を指定します。

  • 軸ステップの省略可能なステップ修飾子部分は、式のどのステップでも指定されていません。

このクエリは、<ProductDescription>要素の<Features>要素の子の<Warranty>要素の子を返します。

結果を次に示します。

<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  

ノード名にはワイルドカード文字を指定します。 したがって、クエリは、<ProductDescription>要素ノードの<Features>要素ノード子のすべての要素ノードの子を返します。

次のクエリは、ワイルドカード文字と共に名前空間が指定されている点を除けば、前のクエリと同じです。 結果として、その名前空間に含まれるすべての子要素ノードが返されます。 <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  

このクエリは、製品カタログ XML ドキュメントのすべての名前空間の <Maintenance> 要素ノードの子を返します。

C: ノード テストでのノードの種類の指定

次の例では、すべてのパス式でノードの種類をノード テストとして指定します。 結果として、すべての式がノード テストに指定した種類のノードを返します。

次のクエリでは、パス式は、3 番目の手順でノードの種類を指定します。

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  

次のクエリでは、次のものが指定されています。

  • パス式には、スラッシュ (/) で区切られた 3 つのステップがあります。

  • これらの各手順では、子軸を指定します。

  • 最初の 2 つの手順ではノードテストとしてノード名を指定し、3 番目のステップではノードの種類をノード テストとして指定します。

  • この式は、<ProductDescription>要素ノードの<Features>要素の子テキスト ノードの子を返します。

返されるテキスト ノードは 1 つだけです。 結果を次に示します。

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  

上のクエリに関して、次の点に注意してください。

  • 2 番目の手順では、ノードの種類をノード テストとして指定します。

  • その結果、式は、 <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() ノード テストに渡すことができます。 この場合、クエリは、name 属性値が引数で指定された文字列リテラルである処理命令を返します。

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) はサポートされていません。 name は引用符で囲む必要があります。