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

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

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

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

Ось

Описание

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, в качестве проверок узлов. Для получения сведений о проверках узла см. раздел Установка проверки узла в шаге выражения пути.

Б. Указание осей 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

В следующем результате выражение возвращает дочерний узел элемента <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>

Если указать ось descendant-or-self вместо оси descendant, то выражение /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] в выражении пути будет добавлен, чтобы гарантировать, что будет возвращено одноэлементное значение.