Поделиться через


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

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

Дополнительные сведения см. в разделе Выражения пути (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.

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

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