nodes() メソッド (xml データ型)nodes() Method (xml Data Type)

適用対象:○SQL Server (2008 以降)○Azure SQL Database×Azure SQL Data Warehouse ×Parallel Data Warehouse THIS TOPIC APPLIES TO:yesSQL Server (starting with 2008)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

Nodes() メソッドは、細分化する場合に便利な xml データ型のインスタンスをリレーショナル データにします。The nodes() method is useful when you want to shred an xml data type instance into relational data. また、このメソッドにより、新しい行にマップされるノードを特定できます。It allows you to identify nodes that will be mapped into a new row.

すべての xml データ型のインスタンスには、コンテキスト ノードが暗黙に用意されています。Every xml data type instance has an implicitly provided context node. 列や変数に格納された XML インスタンスの場合は、ドキュメント ノードがコンテキスト ノードになります。For the XML instance stored in a column or variable, this is the document node. このドキュメント ノードは、すべての xml データ型のインスタンスの最上位に位置する暗黙のノードです。The document node is the implicit node at the top of every xml data type instance.

nodes() メソッドの結果は、元の XML インスタンスの論理コピーを含む行セットです。The result of the nodes() method is a rowset that contains logical copies of the original XML instances. このような論理コピーでは、クエリ式で識別されるいずれかのノードが、すべての行インスタンスのコンテキスト ノードに設定されます。その結果、その後に実行されるクエリはこのようなコンテキスト ノードへ相対移動できます。In these logical copies, the context node of every row instance is set to one of the nodes identified with the query expression, so that subsequent queries can navigate relative to these context nodes.

行セットからは、複数の値を取得できます。You can retrieve multiple values from the rowset. たとえば、value() メソッドを nodes() で返される行セットに適用し、元の XML インスタンスから複数の値を取得できます。For example, you can apply the value() method to the rowset returned by nodes() and retrieve multiple values from the original XML instance. value() メソッドを XML インスタンスに適用すると、値は 1 つしか返されないことに注意してください。Note that the value() method, when applied to the XML instance, returns only one value.

構文Syntax


nodes (XQuery) as Table(Column)  

引数Arguments

XQueryXQuery
XQuery 式の文字列リテラルです。Is a string literal, an XQuery expression. このクエリ式でノードが構築されると、構築されるノードが結果の行セットで公開されます。If the query expression constructs nodes, these constructed nodes are exposed in the resulting rowset. クエリ式の結果が空のシーケンスの場合、結果の行セットは空になります。If the query expression results in an empty sequence, the rowset will be empty. クエリ式で、ノードではなくアトミック値が含まれたシーケンスが静的に返される場合は、静的エラーが発生します。If the query expression statically results in a sequence that contains atomic values instead of nodes, a static error is raised.

テーブル()Table(Column)
結果の行セットのテーブル名と列名です。Is the table name and the column name for the resulting rowset.

RemarksRemarks

たとえば、次のテーブルがあるとします。As an example, assume that you have the following table:

T (ProductModelID int, Instructions xml)  

次の製造手順ドキュメントがこのテーブルに格納されます。The following manufacturing instructions document is stored in the table. 記載しているのはドキュメントの一部のみです。Only a fragment is shown. このドキュメントには 3 つの製造場所が含まれていることに注意してください。Note that there are three manufacturing locations in the document.

<root>  
  <Location LocationID="10"...>  
     <step>...</step>  
     <step>...</step>  
      ...  
  </Location>  
  <Location LocationID="20" ...>  
       ...  
  </Location>  
  <Location LocationID="30" ...>  
       ...  
  </Location>  
</root>  

クエリ式 /root/Location を指定して nodes() メソッドを呼び出すと、次のように 3 つの行を持つ行セットが返されます。各行には元の XML ドキュメントの論理コピーが格納されており、いずれかの <Location> ノードがコンテキスト アイテムに設定されます。A nodes() method invocation with the query expression /root/Location would return a rowset with three rows, each containing a logical copy of the original XML document, and with the context item set to one of the <Location> nodes:

Product  
ModelID      Instructions  
----------------------------------  
1       <root>  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  

             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             </root>  

この行セットには、xml データ型のメソッドを使用してクエリを実行できます。You can then query this rowset by using xml data type methods. 次のクエリを実行すると、生成された行ごとにコンテキスト アイテムのサブツリーが抽出されます。The following query extracts the subtree of the context item for each generated row:

SELECT T2.Loc.query('.')  
FROM   T  
CROSS APPLY Instructions.nodes('/root/Location') as T2(Loc)   

結果を次に示します。This is the result:

ProductModelID  Instructions  
----------------------------------  
1        <Location LocationID="10" ... />  
1        <Location LocationID="20" ... />  
1        <Location LocationID="30" .../>  

返された行セットでは型情報が保持されることに注意してください。Note that the rowset returned has maintained the type information. nodes() メソッドの結果には、query()value()exist()nodes() など、xml データ型のメソッドを適用できます。You can apply xml data type methods, such as query(), value(), exist(), and nodes(), to the result of a nodes() method. ただし、modify() メソッドを適用して XML インスタンスを変更することはできません。However, you cannot apply the modify() method to modify the XML instance.

また、行セットのコンテキスト ノードは具体化できません。Also, the context node in the rowset cannot be materialized. つまり、このコンテキスト ノードは SELECT ステートメントでは使用できません。That is, you cannot use it in a SELECT statement. ただし、IS NULL と COUNT(*) では使用できます。However, you can use it in IS NULL and COUNT(*).

nodes() メソッドを使用するシナリオは、OPENXML (Transact-SQL) を使用する場合と同じです。Scenarios for using the nodes() method are the same as for using OPENXML (Transact-SQL). したがって、XML の行セット ビューが提供されます。This provides a rowset view of the XML. ただし、XML ドキュメントの複数の行が含まれるテーブルに nodes() メソッドを使用するときは、カーソルを使用する必要はありません。However, you do not have to use cursors when you use the nodes() method on a table that contains several rows of XML documents.

nodes() メソッドで返される行セットには名前が付いていないことに注意してください。Note that the rowset returned by the nodes() method is an unnamed rowset. したがって、別名を使用してこれらの行セットに明示的に名前を付ける必要があります。Therefore, it must be explicitly named by using aliasing.

nodes() 関数をユーザー定義関数の結果に直接適用することはできません。The nodes() function cannot be applied directly to the results of a user-defined function. ユーザー定義のスカラー関数の結果と nodes() 関数を使用するには、ユーザー定義関数の結果を変数に割り当てるか、派生テーブルを使用して、ユーザー定義関数の戻り値に列の別名を割り当て、CROSS APPLY を使用して別名から選択します。To use the nodes() function with the result of a scalar user-defined function, you can either assign the result of the user-defined function to a variable or use a derived table to assign a column alias to the user-defined function return value and then use CROSS APPLY to select from the alias.

次の例では、CROSS APPLY を使用し、ユーザー定義関数の結果から選択する方法を示します。The following example shows one way to use CROSS APPLY to select from the result of a user-defined function.

USE AdventureWorks;  
GO  

CREATE FUNCTION XTest()  
RETURNS xml  
AS  
BEGIN  
RETURN '<document/>';  
END;  
GO  

SELECT A2.B.query('.')  
FROM  
(SELECT dbo.XTest()) AS A1(X)   
CROSS APPLY X.nodes('.') A2(B);  
GO  

DROP FUNCTION XTest;  
GO  

使用例Examples

xml 型の変数に対する nodes() メソッドの使用Using nodes() method against a variable of xml type

次の例では、<Root> 最上位要素と 3 つの <row> 子要素が含まれる XML ドキュメントを使用します。In the following example, there is an XML document that has a <Root> top-level element and three <row> child elements. このクエリでは、nodes() メソッドを使用して、各 <row> 要素に 1 つずつ別のコンテキスト ノードを設定します。The query uses the nodes() method to set separate context nodes, one for each <row> element. nodes() メソッドにより、3 つの行を持つ行セットが返されます。The nodes() method returns a rowset with three rows. 各行には元の XML の論理コピーが含まれ、それぞれのコンテキスト ノードで元のドキュメントの異なる <row> 要素が識別されます。Each row has a logical copy of the original XML, with each context node identifying a different <row> element in the original document.

その後、次のクエリを実行すると、各行のコンテキスト ノードが返されます。The query then returns the context node from each row:

DECLARE @x xml   
SET @x='<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>'  
SELECT T.c.query('.') AS result  
FROM   @x.nodes('/Root/row') T(c)  
GO  

次に結果を示します。The following is the result. この例では、クエリのメソッドでコンテキスト アイテムとそのコンテンツが返されます。In this example, the query method returns the context item and its content:

<row id="1"><name>Larry</name><oflw>some text</oflw></row>  
<row id="2"><name>moe</name></row>  
<row id="3"/>  

次のように、親アクセサーをコンテキスト ノードに適用すると、3 つのノードすべての <Root> 要素が返されます。Applying the parent accessor on the context nodes returns the <Root> element for all three:

SELECT T.c.query('..') AS result  
FROM   @x.nodes('/Root/row') T(c)  
go  

結果を次に示します。This is the result:

<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  

xml 型の列に対する nodes() メソッドの指定Specifying the nodes() method against a column of xml type

この例では、ProductModel テーブルの xml 型の Instructions 列に格納されている、自転車の製造手順を使用します。The bicycle manufacturing instructions are used in this example and are stored in the Instructions xml type column of the ProductModel table.

次の例では、ProductModel テーブルの xml 型の Instructions 列に対して nodes() メソッドを指定します。In the following example, the nodes() method is specified against the Instructions column of xml type in the ProductModel table.

/MI:root/MI:Location パスを指定することで、nodes() メソッドでは <Location> 要素がコンテキスト ノードに設定されます。The nodes() method sets the <Location> elements as context nodes by specifying the /MI:root/MI:Location path. 結果の行セットには、ドキュメントの各 <Location> ノードに 1 つずつ元のドキュメントの論理コピーが含まれます。また、その <Location> 要素がコンテキスト ノードに設定されます。The resulting rowset includes logical copies of the original document, one for each <Location> node in the document, with the context node set to the <Location> element. したがって、nodes() 関数から返されるのは、<Location> コンテキスト ノードのセットです。Therefore, the nodes() function gives a set of <Location> context nodes.

この行セットに対する query() メソッドでは self::node が要求されるため、各行の <Location> 要素が返されます。The query() method against this rowset requests self::node and, therefore, returns the <Location> element in each row.

この例のクエリでは、各 <Location> 要素が、特定の製品モデルの製造手順ドキュメントのコンテキスト ノードとして設定されます。In this example, the query sets each <Location> element as a context node in the manufacturing instructions document of a specific product model. これらのコンテキスト ノードを使用して、次のような値を取得できます。You can use these context nodes to retrieve values such as the following:

  • 各 <Location> の場所 IDFind Location IDs in each <Location>

  • 各 <Location> の製造手順 (<step> 子要素)Retrieve manufacturing steps (<step> child elements) in each <Location>

    このクエリでは、'.' メソッドで self::node() に対する省略構文 query() を指定して、コンテキスト アイテムを返しています。This query returns the context item, in which the abbreviated syntax '.' for self::node() is specified, in the query() method.

    次のことを考慮してください。Note the following:

  • nodes() メソッドは Instructions 列に適用され、行セット T (C) を返します。The nodes() method is applied to the Instructions column and returns a rowset, T (C). この行セットには、/root/Location をコンテキスト アイテムとして、元の製造手順ドキュメントの論理コピーが格納されています。This rowset contains logical copies of the original manufacturing instructions document with /root/Location as the context item.

  • CROSS APPLY により、Instructions テーブルの各行に nodes() が適用され、結果セットを生成する行のみが返されます。CROSS APPLY applies nodes() to each row in the Instructions table and returns only the rows that produce a result set.

    SELECT C.query('.') as result  
    FROM Production.ProductModel  
    CROSS APPLY Instructions.nodes('  
    declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
    /MI:root/MI:Location') as T(C)  
    WHERE ProductModelID=7  
    

    結果の一部を次に示します。This is the partial result:

    <MI:Location LocationID="10"  ...>  
       <MI:step ... />  
          ...  
    </MI:Location>  
    <MI:Location LocationID="20"  ... >  
        <MI:step ... />  
          ...  
    </MI:Location>  
    ...  
    

別の nodes() メソッドにより返された行セットに対する nodes() の適用Applying nodes() to the rowset returned by another nodes() method

次のコードでは、XML ドキュメントに対し、Instructions テーブルの ProductModel 列に格納されている製造手順をクエリしています。The following code queries the XML documents for the manufacturing instructions in the Instructions column of ProductModel table. このクエリでは、製品モデル ID、製造場所、および製造手順が含まれた行セットが返されます。The query returns a rowset that contains the product model ID, manufacturing locations, and manufacturing steps.

次のことを考慮してください。Note the following:

  • nodes() メソッドは Instructions 列に適用され、T1 (Locations) 行セットを返します。The nodes() method is applied to the Instructions column and returns the T1 (Locations) rowset. この行セットには、/root/Location 要素をコンテキスト アイテムとして、元の製造手順ドキュメントの論理コピーが格納されています。This rowset contains logical copies of the original manufacturing instructions document, with /root/Location element as the item context.

  • nodes()T1 (Locations) 行セットに適用され、T2 (steps) 行セットを返します。nodes() is applied to the T1 (Locations) rowset and returns the T2 (steps) rowset. この行セットには、/root/Location/step 要素をコンテキスト アイテムとして、元の製造手順ドキュメントの論理コピーが格納されています。This rowset contains logical copies of the original manufacturing instructions document, with /root/Location/step element as the item context.

SELECT ProductModelID, Locations.value('./@LocationID','int') as LocID,  
steps.query('.') as Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
/MI:root/MI:Location') as T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
./MI:step ') as T2(steps)         
WHERE ProductModelID=7         
GO         

結果を次に示します。This is the result:

ProductModelID LocID Step         
----------------------------         
7      10   <step ... />         
7      10   <step ... />         
...         
7      20   <step ... />         
7      20   <step ... />         
7      20   <step ... />         
...         

このクエリでは、MI プレフィックスを 2 回宣言しています。The query declares the MI prefix two times. 代わりに WITH XMLNAMESPACES を使用し、このプレフィックスを 1 回宣言してクエリで使用することもできます。Instead, you can use WITH XMLNAMESPACES to declare the prefix one time and use it in the query:

WITH XMLNAMESPACES (  
   'http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions'  AS MI)  

SELECT ProductModelID, Locations.value('./@LocationID','int') as LocID,  
steps.query('.') as Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
/MI:root/MI:Location') as T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
./MI:step ') as T2(steps)         
WHERE ProductModelID=7         
GO    

参照See Also

WITH XMLNAMESPACES を使用したクエリへの名前空間の追加 Add Namespaces to Queries with WITH XMLNAMESPACES
XML データのインスタンスの作成 Create Instances of XML Data
xml データ型メソッドxml Data Type Methods