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

適用対象:SQL Server

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

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

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

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

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

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

注意

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::ProductModelID2 つのステップで構成されます。 どちらのステップでも、ノード名をノード テストとして指定しています。 また、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. ノード テストでのノード名の指定

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

次のクエリ式は、テーブルに <Warranty> 格納されている製品カタログ XML ドキュメントから 要素を Production.ProductModel 返します。

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 つのステップはすべて、ノード テストとして子軸とノード名を指定します。

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

クエリは、 要素の <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. ノード テストでのノードの種類の指定

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

次のクエリでは、path 式は 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 番目の手順ではノード テストとしてノードの種類を指定します。

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

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 は引用符で囲む必要があります。