在路径表达式步骤中指定轴

路径表达式中的轴步骤包括以下部分:

有关详细信息,请参阅 路径表达式 (XQuery)

SQL Server 中的 XQuery 实现支持以下轴步骤:

Axis

说明

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 轴。对 Production.ProductModel 表中的生产说明 XML 文档执行该表达式时,返回 <root> 元素的 <Location> 元素节点子级的 LocationID 属性。

示例

本主题中的查询示例是针对 AdventureWorks 数据库中的 xml 类型列指定的。有关这些列的信息,请参阅 AdventureWorks 数据库中的 xml 数据类型表示形式

A. 指定 child 轴

以下查询针对某个特定产品型号,从 Production.ProductModel 表中存储的产品目录说明中检索 <ProductDescription> 元素节点的 <Features> 元素节点子级。

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

请注意上述查询的以下方面:

  • xml 数据类型的 query() 方法指定路径表达式。

  • 路径表达式中的两个步骤都指定一个 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

在以下结果中,表达式返回 <a> 元素节点的 <b> 元素节点子级:

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

在此表达式中,如果为路径表达式指定了 descendant 轴

/child::a/child::b/descendant::*,则您请求的是 <b> 元素节点的所有后代。

节点测试中的星号 (*) 以一个节点测试表示节点名称。因此,descendant 轴的主节点类型(元素节点)确定返回节点的类型。即表达式返回所有元素节点。但不返回文本节点。有关主节点类型及其与节点测试的关系的详细信息,请参阅指定路径表达式步骤中的节点测试主题。

此时返回元素节点 <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 数据库的查询,检索 <ProductDescription> 元素的 <Features> 元素子级的所有后代元素节点:

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

C. 指定 parent 轴

以下查询从 Production.ProductModel 表中存储的产品目录 XML 文档返回 <ProductDescription> 元素的 <Summary> 元素子级。

此示例使用 parent 轴来返回 <Feature> 元素的父级,并检索 <ProductDescription> 元素的 <Summary> 元素子级。

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 轴。您可以重写该表达式,不使用 parent 轴,如下所示:

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

以下是一个关于 parent 轴的更为有用的示例。

ProductModel 表的 CatalogDescription 列中存储的每个产品型号目录说明都有 <ProductDescription> 元素,该元素包含 ProductModelID 属性和 <Features> 子元素,如以下片段所示:

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

查询在 FLWOR 语句中设置了一个迭代器变量 $f,以返回 <Features> 元素的元素子级。有关详细信息,请参阅 FLWOR 语句和迭代 (XQuery)。对于每个功能,return 子句都构造一个以下形式的 XML:

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

为了给每个 <Feature> 元素添加 ProductModelID,指定了 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],这是为了确保返回单一值。