Выражения пути — указание оси
Область применения: SQL Server
Шаг оси в выражении пути содержит следующие компоненты:
Дополнительные сведения см. в разделе "Выражения пути" (XQuery).
Реализация XQuery в SQL Server поддерживает следующие шаги оси.
Axis | Description |
---|---|
child | Возвращает дочерние элементы контекстного узла. |
потомок | Возвращает всех потомков контекстного узла. |
parent | Возвращает родительский элемент контекстного узла. |
атрибут | Возвращает атрибуты контекстного узла. |
сам | Возвращает сам контекстный узел. |
descendant-or-self | Возвращает сам контекстный узел и всех его потомков. |
Все эти оси, кроме родительской оси, являются осями вперед. Родительская ось является обратной осью, так как она выполняет поиск назад в иерархии документов. Например, относительное выражение пути child::ProductDescription/child::Summary
имеет два шага, и каждый шаг указывает ось child
. Первый шаг извлекает дочерние <элементы ProductDescription> узла контекста. Для каждого <узла элемента ProductDescription> второй шаг извлекает дочерние <узлы элемента Summary> .
Относительное выражение пути child::root/child::Location/attribute::LocationID
имеет три шага. Каждый из первых двух шагов указывает ось child
, а третий этап указывает ось attribute
. При выполнении xml-документов инструкций по производству в таблице Production.ProductModel выражение возвращает LocationID
атрибут дочернего <элемента элемента Location> корневого <> элемента.
Примеры
Примеры запросов в этом разделе указываются для столбцов типа 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
, в качестве проверок узлов. Сведения о тестах узлов см. в разделе "Указание теста узла" на шаге выражения пути.
B. Указание осей 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>
Если указать ось потомка или самозадавлия вместо оси потомка, /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
В. Указание родительской оси
Следующий запрос возвращает дочерний <<>ProductDescription
Summary
> элемент элемента в 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]
в выражении пути будет добавлен, чтобы гарантировать, что будет возвращено одноэлементное значение.