Указание оси на этапе выражения пути

Этап указания оси в выражении пути включает в себя следующие компоненты:

Дополнительные сведения см. в разделе Выражения пути (XQuery).

Выполнение XQuery в SQL Server 2005 поддерживает следующие этапы оси:

Ось Описание

child

Возвращает дочерние элементы контекстного узла.

descendant

Возвращает всех потомков контекстного узла.

parent

Возвращает родительский элемент контекстного узла.

attribute

Возвращает атрибуты контекстного узла.

self

Возвращает сам контекстный узел.

descendant-or-self

Возвращает сам контекстный узел и всех его потомков.

Все эти оси, кроме оси parent, являются направленными вперед осями. Ось parent — обратная ось, потому что она ищет в обратном направлении в иерархии документа. Например, относительное выражение пути child::ProductDescription/child::Summary имеет два этапа, и каждый этап указывает ось child. Первый этап извлекает дочерний элемент <ProductDescription> контекстного узла. Для каждого узла элемента <ProductDescription> второй этап извлекает дочерний узел элемента <Summary>.

Относительное выражение пути child::root/child::Location/attribute::LocationID имеет три этапа. Каждый из первых двух этапов указывает ось child, а третий этап указывает ось attribute. При выполнении по отношению к производственным инструкциям XML-документов в таблице Production.ProductModel это выражение возвращает атрибут LocationID дочернего узла элемента <Location> элемента <root>.

Примеры

Примеры запросов в этой теме указаны по отношению к типу столбцов xml в базе данных AdventureWorks. Для получения сведений об этих столбцах см. раздел Представление типов xml-данных в базе данных AdventureWorks.

А. Указание дочерней оси

Для определенной модели продукта следующий запрос извлекает дочерние узлы-элементы <Features> для узла-элемента <ProductDescription> из описания каталога продукта, хранящегося в таблице Production.ProductModel.

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

Отметьте следующие особенности этого запроса.

  • Метод query() типа данных xml указывает выражение пути.
  • Оба этапа в выражении пути указывают ось child и имена узлов, ProductDescription и Features, в качестве проверок узлов. Для получения сведений о проверках узла см. раздел Установка проверки узла в шаге выражения пути.

Б. Указание осей потомков или потомков и самого узла

Следующий пример использует ось потомков, а также ось потомков и самого себя. Запрос в этом примере указан по отношению к переменной типа 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

В следующем результате выражение возвращает дочерний узел-элемент <b> для узла-элемента <a>:

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

Если в этом выражении указать ось потомков для данного выражения пути,

/child::a/child::b/descendant::*, то будут запрошены все потомки узла элемента <b>.

Звездочка (*) в проверке узла представляет имя узла как проверку узла. Поэтому тип первичного узла оси потомков, узел-элемент, определяет типы возвращаемых узлов. Таким образом, выражение возвращает все узлы-элементы. Текстовые узлы возвращены не будут. Дополнительные сведения о типе первичного узла и его отношениях с проверкой узла см. в разделе Установка проверки узла в шаге выражения пути.

Будут возвращены узлы-элементы <c> и <d>, как показано в следующем результате:

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

Если указать ось потомков или самого себя вместо оси потомков, то выражение /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 извлекает все узлы-элементы, являющиеся потомками дочернего элемента <Features> для элемента <ProductDescription>:

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

В. Указание родительской оси

Следующий запрос возвращает дочерний элемент <Summary> элемента <ProductDescription> в XML-документе каталога продукта, сохраненном в таблице Production.ProductModel.

Этот пример использует родительскую ось для возврата к родителю элемента <Feature> и извлечения дочернего элемента <Summary> элемента <ProductDescription>.

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. Можно переписать это выражение без родительской оси так, как показано ниже:

  /child::PD:ProductDescription[child::PD:Features]/child::PD:Summary

Более полезный пример родительской оси представлен в следующем примере.

Каждое описание для каталога модели продукта, сохраненное в столбце CatalogDescription таблицы ProductModel, имеет элемент <ProductDescription>, который обладает атрибутом ProductModelID и дочерним элементом <Features>, как показано в следующем фрагменте:

<ProductDescription ProductModelID="..." >
  ...
  <Features>
    <Feature1>...</Feature1>
    <Feature2>...</Feature2>
   ...
</ProductDescription>

Запрос устанавливает в инструкции FLWOR переменную-итератор, $f, с целью возврата дочерних элементов для элемента <Features>. Дополнительные сведения см. в разделе Итерация и инструкция FLWOR (XQuery). Для каждой характеристики предложение return создает XML следующего вида:

<Feature ProductModelID="...">...</Feature>
<Feature ProductModelID="...">...</Feature>

Чтобы добавить ProductModelID для каждого элемента <Feature>, указана ось 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] в выражении пути будет добавлен, чтобы гарантировать, что будет возвращено одноэлементное значение.