第四篇旨在对路径表达式中的步骤(轴步骤 、一般步骤)详细说明。
-- 本文来自happyflystone -优快云博客,
-- 转载请标明出处:http://blog.youkuaiyun.com/happyflystone
------------------------------------------------------------------------
1、 先说说轴
轴定义移动的方向,从上下文节点开始,导航到在轴指定的方向上可访问的那些节点。用轴步骤得用到上面一节说的全文、缩写语法及绝对、相对路径。此外假设你对此已经有了解。
下面我们介绍一下2005下的XML支持哪些轴:
Axis 说明
child 返回上下文节点的子级
descendant 返回上下文节点的所有后代
parent 返回上下文节点的父级
attribute 返回上下文节点的属性
self 返回上下文节点本身
descendant-or-self 返回上下文节点及其所有后代
很显然,我们可以想像一下这些轴里除了parent 轴是向反方向的,其它全是正向,所以我们又称除了parent以外的轴是正向轴,而parent 轴是反向轴,其实我们简单点理解一下就是一个是正向向下搜索,一个是反向向上搜索。
好,下面还是以例子来说明问题:
A、下面演示用child轴操作一下查询(注意下面查询语句包括了绝对与相对路径表达式)
declare @xml xml
set @xml = '<address>
<exam>
<name> flystone1 </name>
<street> 1401 Main Street </street>
<city state="NC">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
<exam>
<name> flystone2 </name>
<street> 1402 Main Street </street>
<city state="NM">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
</address>
'
select @xml.query('/child::address/child::exam')
select @xml.query('//exam')
select @xml.query('/address/exam')
select @xml.query('address/exam')
select @xml.query('child::address/child::exam')
/*
--------------------------------------------------------------------
<exam><name> flystone1 </name><street> 1401 Main Street </street><city state="NC">Anytown</city><postal-code> 210000 </postal-code></exam><exam><name> flystone2 </name><street> 1402 Main Street </street><city state="NM">Anytown</city><postal-code>
(1 行受影响)
*/
B、下面看看descendant轴、descendant-or-self轴,其实后者只是比前多了上下文节点,大家看看例子就知道
declare @xml xml
set @xml = '<address>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone1</lastname>
</name>
<street> 1401 Main Street </street>
<city state="NC">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone2</lastname>
</name>
<street> 1402 Main Street </street>
<city state="NM">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
</address>
'
select @xml.query('/child::address/child::exam/child::name/descendant::*')
select @xml.query('//./address/exam/name/descendant::*')
select @xml.query('/./address/exam/name/descendant::*')
select @xml.query('./address/exam/name/descendant::*')
select @xml.query('/address/exam/name/descendant::*')
select @xml.query('address/exam/name/descendant::*')
/*
-----------------------------------------
<firstname>fly</firstname><lastname>stone1</lastname><firstname>fly</firstname><lastname>stone2</lastname>
(1 行受影响)
*/
declare @xml xml
set @xml = '<address>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone1</lastname>
</name>
<street> 1401 Main Street </street>
<city state="NC">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone2</lastname>
</name>
<street> 1402 Main Street </street>
<city state="NM">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
</address>
'
select @xml.query('/child::address/child::exam/child::name/descendant-or-self::*')
select @xml.query('//./address/exam/name/descendant-or-self::*')
select @xml.query('/./address/exam/name/descendant-or-self::*')
select @xml.query('./address/exam/name/descendant-or-self::*')
select @xml.query('/address/exam/name/descendant-or-self::*')
select @xml.query('address/exam/name/descendant-or-self::*')
/*
------------------------------------------------------------
<name><firstname>fly</firstname><lastname>stone1</lastname></name><firstname>fly</firstname><lastname>stone1</lastname><name><firstname>fly</firstname><lastname>stone2</lastname></name><firstname>fly</firstname><lastname>stone2</lastname>
(1 行受影响)
*/
C、下面看看parent轴的用法 :
declare @xml xml
set @xml = '<address>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone1</lastname>
</name>
<street> 1401 Main Street </street>
<city state="NC">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
<exam>
<name>
<firstname>fly</firstname>
<lastname>stone2</lastname>
</name>
<street> 1402 Main Street </street>
<city state="NM">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
</address>
'
select @xml.query('/child::address/child::exam/child::name/parent::exam')
select @xml.query('//name/parent::exam')
--先把上下文定位到name节点然后再找父节点
/*
------------------------------------------------------------------
<exam><name><firstname>fly</firstname><lastname>stone1</lastname></name><street> 1401 Main Street </street><city state="NC">Anytown</city><postal-code> 210000 </postal-code></exam><exam><name><firstname>fly</firstname><lastname>stone2</lastname></name><street> 1402 Main Street </street><city state="NM">Anytown</city><postal-code> 210000 </postal-code></exam>
(1 行受影响)
*/
在SQL SERVER2005看到一个有意思的东东,我们来试试(里面涉及FLWOR 语句大家先跳过,以后我们再细说FLWOR)
declare @xml xml
set @xml = '
<address>
<exam id="1">
<name>
<firstname>fly</firstname>
<lastname>stone1</lastname>
</name>
<street> 1401 Main Street </street>
<city state="NC">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
<exam id="2">
<name>
<firstname>fly</firstname>
<lastname>stone2</lastname>
</name>
<street> 1402 Main Street </street>
<city state="NM">Anytown</city>
<postal-code> 210000 </postal-code>
</exam>
</address>
'
select @xml.query('
for $f in /child::address/child::exam/name/child::*
return
<name
id="{($f/parent::name/parent::exam/attribute::id)[1]}" >
{ $f }
</name>
')
select @xml.query('
for $f in //name/child::*
return
<name
id="{($f/parent::name/parent::exam/attribute::id)[1]}" >
{ $f }
</name>
')
/*
------------------------------------------------------------------
<name id="1">
<firstname>fly</firstname>
</name>
<name id="1">
<lastname>stone1</lastname>
</name>
<name id="2">
<firstname>fly</firstname>
</name>
<name id="2">
<lastname>stone2</lastname>
</name>
(1 行受影响)
*/
请注意,在路径表达式中添加了谓词 [1],这是为了确保返回单一值。因为我们这样测试也没问题:
select @xml.query('
for $f in //name/child::*
return
<name
id="{($f/parent::name/parent::exam/attribute::id)}" >
{ $f }
</name>
')
2、 节点测试
节点测试是一个条件,在步骤中选定的所有节点都必须满节点名测试或节点类型测试。节点名称很好理解,就是<>内的东东,下面先说说节点类型:
|
节点类型 |
返回 |
本文详细介绍XPath中的路径表达式步骤,包括轴步骤和节点测试的概念。通过具体示例讲解了如何使用child、descendant、parent等轴进行节点查询,并解释了节点测试的作用。
1385

被折叠的 条评论
为什么被折叠?



