Указание оси на шаге выражения пути
Шаг указания оси в выражении пути включает в себя следующие компоненты:
Дополнительные сведения см. в разделе Выражения пути (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 в базе данных База данных AdventureWorks2008R2. Для получения сведений об этих столбцах см. раздел Представление типов данных XML в базе данных AdventureWorks2008R2.
А. Указание дочерней оси
Для определенной модели продукта следующий запрос получает дочерние узлы-элементы <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>
Следующий образец запроса к базе данных База данных AdventureWorks2008R2 получает все узлы элементов, являющихся потомками дочернего элемента <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 Adventure Works 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] в выражении пути будет добавлен, чтобы гарантировать, что будет возвращено одноэлементное значение.