Метод nodes() (тип данных xml)nodes() Method (xml Data Type)

ОБЛАСТЬ ПРИМЕНЕНИЯ:даSQL Server (начиная с 2008)даБаза данных SQL AzureдаХранилище данных SQL AzureнетParallel Data WarehouseAPPLIES TO: yesSQL Server (starting with 2008) yesAzure SQL Database noAzure 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 node 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 that is identified with the query expression. Таким образом последующие запросы могут перемещаться относительно этих контекстных узлов.This way, later 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, возвращает только одно значение.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 is empty as well. Если статическим результатом выражения запроса является последовательность, которая вместо узлов содержит атомарные значения, возникает статическая ошибка.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. Обратите внимание, что в документе указываются три места производства.Notice 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>  

Вызов метода nodes() с выражением запроса /root/Location возвращает набор из трех строк, каждая из которых содержит логическую копию исходного 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)   

Результат:Here is the result:

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

Возвращаемый набор строк сохраняет информацию о типе.The rowset returned has maintained the type information. Методы типа данных xml (query(), value(), exist() и nodes()) могут применяться к результату, возвращенному методом nodes().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 can't apply the modify() method to modify the XML instance.

Кроме того, контекстный узел в наборе строк не может быть материализован.Also, the context node in the rowset can't be materialized. Это означает, что вы не можете использовать его в инструкции SELECT.That is, you can't use it in a SELECT statement. Однако он может использоваться в выражениях IS NULL и COUNT(*).However, you can use it in IS NULL and COUNT(*).

Сценарии применения метода nodes() и инструкции OPENXML (Transact-SQL) совпадают. Тем самым обеспечивается представление набора строк XML.Scenarios for using the nodes() method are the same as for using OPENXML (Transact-SQL), which provides a rowset view of the XML. Однако при применении метода nodes() в таблице, содержащей несколько строк XML-документов, необязательно использовать курсоры.However, you don't have to use cursors when you use the nodes() method on a table that contains several rows of XML documents.

Набор строк, возвращаемый методом nodes(), является неименованным набором строк.The rowset returned by the nodes() method is an unnamed rowset. Поэтому он должен быть явно именован с помощью механизма псевдонимов.So, it must be explicitly named by using aliasing.

Функция nodes() не может быть применена непосредственно к результатам определенной пользователем функции.The nodes() function can't be applied directly to the results of a user-defined function. Чтобы использовать функцию nodes() с результатом скалярной функции, определенной пользователем, вы можете: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
  • воспользоваться производной таблицей и присвоить псевдоним столбца возвращаемому значению определенной пользователем функции, после чего применить инструкцию CROSS APPLY, чтобы выбрать данные из псевдонима.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

Применение метода nodes() к переменной типа данных xmlUsing nodes() method against a variable of xml type

В этом примере рассматривается XML-документ с элементом верхнего уровня <Root> и тремя дочерними элементами <row>.In the following example, there's an XML document that has a <Root> top-level element and three <row> child elements. Запрос использует метод nodes() для разделения контекстных узлов, по одному для каждого элемента <row>.The query uses the nodes() method to set separate context nodes, one for each <row> element. Метод nodes() возвращает набор из трех строк.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  

В следующем примере метод запроса возвращает элемент контекста и его содержимое:In the following example result, 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"/>  

Применение родительского метода доступа на контекстных узлах возвращает элемент <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  

Результат:Here 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>  

Задание метода nodes() для столбца типа данных xmlSpecifying the nodes() method against a column of xml type

В этом примере использованы инструкции по производству велосипедов, которые хранятся в столбце Instructions типа xml в таблице ProductModel.The bicycle manufacturing instructions are used in this example and are stored in the Instructions xml type column of the ProductModel table.

В следующем примере метод nodes() применяется к столбцу Instructions типа xml в таблице ProductModel.In the following example, the nodes() method is specified against the Instructions column of xml type in the ProductModel table.

Метод nodes() устанавливает элементы <Location> как контекстные узлы, задавая путь /MI:root/MI:Location.The nodes() method sets the <Location> elements as context nodes by specifying the /MI:root/MI:Location path. Результирующий набор строк включает в себя логические копии исходного документа, одну для каждого узла <Location> в документе, с контекстным узлом, установленным в элемент <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>.As a result, the nodes() function gives a set of <Location> context nodes.

Метод query(), применяемый к этому набору строк, запрашивает self::node и возвращает элемент <Location> для каждой строки.The query() method against this rowset requests self::node and 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 these:

  • Найти идентификаторы LocationID в каждом элементе <Location>Find Location IDs in each <Location>

  • Получить шаги производства (дочерние элементы <step>) в каждом элементе <Location>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 применяет метод nodes() к каждой строке в таблице Instructions и возвращает только строки, образующие результирующий набор.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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
    /MI:root/MI:Location') as T(C)  
    WHERE ProductModelID=7  
    

    Частичный результат:Here 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

В следующем коде из столбца Instructions таблицы ProductModel запрашиваются XML-документы, составляющие руководство по изготовлению.The following code queries the XML documents for the manufacturing instructions in the Instructions column of ProductModel table. Запрос возвращает набор строк, содержащий идентификатор производственной модели, места производства и шаги производства.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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
/MI:root/MI:Location') as T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
./MI:step ') as T2(steps)         
WHERE ProductModelID=7         
GO         

Результат:Here is the result:

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

В запросе префикс MI объявляется два раза.The query declares the MI prefix two times. Вместо этого можно воспользоваться WITH XMLNAMESPACES, чтобы объявить этот префикс один раз и использовать его в запросе:Instead, you can use WITH XMLNAMESPACES to declare the prefix one time and use it in the query:

WITH XMLNAMESPACES (  
   'https://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
Методы для типа данных XMLxml Data Type Methods