パス式のステップでの軸の指定
パス式の軸ステップには、次のコンポーネントが含まれてます。
詳細については、「パス式 (XQuery)」を参照してください。
SQL Server の XQuery 実装では、次の軸ステップがサポートされています。
軸 |
説明 |
---|---|
child |
コンテキスト ノードの子を返します。 |
descendant |
コンテキスト ノードのすべての子孫を返します。 |
parent |
コンテキスト ノードの親を返します。 |
attribute |
コンテキスト ノードの属性を返します。 |
self |
コンテキスト ノード自身を返します。 |
descendant-or-self |
コンテキスト ノード自身とその子孫をすべて返します。 |
parent 軸以外のすべての軸は順方向軸です。 parent 軸は、ドキュメント階層内を逆方向に検索するので逆方向軸です。 たとえば、相対パス式 child::ProductDescription/child::Summary には 2 つのステップがあり、各ステップが child 軸を指定します。 最初のステップでは、コンテキスト ノードの <ProductDescription> 子要素が取得されます。 2 番目のステップでは、<ProductDescription> 要素ノードごとに、<Summary> 子要素ノードが取得されます。
相対パス式 child::root/child::Location/attribute::LocationID には 3 つのステップがあります。 最初の 2 つのステップは、それぞれ child 軸を指定します。3 番目のステップは attribute 軸を指定します。 この式が、Production.ProductModel テーブルの製造手順 XML ドキュメントに対して実行されると、<root> 要素の <Location> 子要素ノードの LocationID 属性を返します。
使用例
このトピックのクエリ例は AdventureWorks データベースの xml 型の列に対して指定されています。
A. child 軸の指定
次のクエリは、特定の製品モデルについて、Production.ProductModel テーブルに保存されている製品カタログの説明から <ProductDescription> 要素ノードの <Features> 子要素ノードを取得します。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features')
FROM Production.ProductModel
WHERE ProductModelID=19
上のクエリに関して、次の点に注意してください。
xml データ型の query() メソッドでパス式を指定します。
パス式の両方のステップが、child 軸およびノード名 (ProductDescription、Features) をノード テストとして指定しています。 ノード テストの詳細については、「パス式のステップでのノード テストの指定」を参照してください。
B. descendant 軸と descendant-or-self 軸の指定
次の例では、descendant 軸と descendant-or-self 軸を使用します。 この例のクエリは xml 型の変数に対して指定されます。 XML インスタンスは、生成された結果の違いをわかりやすく示すために単純化してあります。
declare @x xml
set @x='
<a>
<b>text1
<c>text2
<d>text3</d>
</c>
</b>
</a>'
declare @y xml
set @y = @x.query('
/child::a/child::b
')
select @y
次の結果では、式から <a> 要素ノードの <b> 子要素ノードが返されます。
<b>text1
<c>text2
<d>text3</d>
</c>
</b>
この式で、
パス式 /child::a/child::b/descendant::* に descendants 軸を指定すると、これは <b> 要素ノードのすべての子孫を要求することになります。
ノード テストのアスタリスク (*) によって、ノード名がノードテストとして表されます。 そのため、descendant 軸の主ノード型 (要素ノード) によって、返されるノードの型が決まります。 つまり、式はすべて要素ノードを返します。 テキスト ノードは返されません。 主ノード型、および主ノード型とノード テストの関係の詳細については「パス式のステップでのノード テストの指定」を参照してください。
つまり、次の結果に示すように、要素ノード <c> と <d> が返されます。
<c>text2
<d>text3</d>
</c>
<d>text3</d>
descendant 軸の代わりに descendant-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>
AdventureWorks データベースに対する次のサンプル クエリは、<ProductDescription> 要素の <Features> 子要素ノードの子孫であるすべての要素ノードを取得します。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features/descendant::*
')
FROM Production.ProductModel
WHERE ProductModelID=19
C. parent 軸の指定
次のクエリは、Production.ProductModel テーブルに保存されている製品カタログ XML ドキュメントの <ProductDescription> 要素の <Summary> 子要素を返します。
この例では、parent 軸を使用して、<Feature> 要素の親を返し、<ProductDescription> 要素の <Summary> 子要素を取得します。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features/parent::PD:ProductDescription/child::PD:Summary
')
FROM Production.ProductModel
WHERE ProductModelID=19
このクエリ例では、パス式で parent 軸が使用されています。 次に示すように、この式を parent 軸を使用せずに書き直すこともできます。
/child::PD:ProductDescription[child::PD:Features]/child::PD:Summary
次の例では、parent 軸の有用な使い方を示します。
次のフラグメントに示すように、ProductModel テーブルの CatalogDescription 列に保存されている各製品モデル カタログの説明には、ProductModelID 属性と、<Features> 子要素を持つ <ProductDescription> 要素が含まれています。
<ProductDescription ProductModelID="..." >
...
<Features>
<Feature1>...</Feature1>
<Feature2>...</Feature2>
...
</ProductDescription>
クエリでは、FLWOR ステートメントで反復子変数 $f を設定し、<Features> 要素の子要素を返します。 詳細については、「FLWOR ステートメントと繰り返し (XQuery)」を参照してください。 製品特徴ごとに、return 句によって次の形式で XML が構築されます。
<Feature ProductModelID="...">...</Feature>
<Feature ProductModelID="...">...</Feature>
各 <Feature> 要素に ProductModelID を追加するには、parent 軸を指定します。
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";
for $f in /child::PD:ProductDescription/child::PD:Features/child::*
return
<Feature
ProductModelID="{ ($f/parent::PD:Features/parent::PD:ProductDescription/attribute::ProductModelID)[1]}" >
{ $f }
</Feature>
')
FROM Production.ProductModel
WHERE ProductModelID=19
結果の一部を次に示します。
<Feature ProductModelID="19">
<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>
</Feature>
<Feature ProductModelID="19">
<wm:Maintenance
xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<wm:NoOfYears>10 years</wm:NoOfYears>
<wm:Description>maintenance contract available through your dealer
or any AdventureWorks retail store.</wm:Description>
</wm:Maintenance>
</Feature>
<Feature ProductModelID="19">
<p1:wheel
xmlns:p1="https://www.adventure-works.com/schemas/OtherFeatures">
High performance wheels.
</p1:wheel>
</Feature>
必ずシングルトン値を返せるように、パス式に述語 [1] が追加されていることに注意してください。