Select XQuery 3.0 中的元素范围
Select range of elements in XQuery 3.0
我有以下xml数据结构
<journey>
<leg origin='a' dest='b' />
<leg origin='b' dest='c' />
<leg origin='c' dest='d' />
<leg origin='d' dest='e' />
<leg origin='e' dest='f' />
... and so on
</journey>
我想 select leg
从 origin='b'
到 dest='e'
的元素
我试过使用翻滚 window, following-sibling,但似乎只能匹配第一个和最后一个元素,中间没有任何元素。
我在 BaseX 8.6 中使用 XQuery 3.0
由于最初的问题并未给出所有范围条件,因此我提供了几个答案。所有这些都基于相同的查询序言和以下假设(可能还有其他假设):
- 搜索到的出发地和目的地存在
- 所有起点和终点只出现一次
- 没有循环(例如
b
→c
→b
)
查询序言
declare variable $JOURNEY :=
<journey>
<leg origin='a' dest='b' />
<leg origin='b' dest='c' />
<leg origin='c' dest='d' />
<leg origin='d' dest='e' />
<leg origin='e' dest='f' />
</journey>;
declare variable $ORIGIN := 'b';
declare variable $DEST := 'e';
使用翻滚window
假设:目的地出现在起点之后。
for tumbling window $legs in $JOURNEY/leg
start $s when $s/@origin = $ORIGIN
end $e when $e/@dest = $DEST
return $legs
使用following-sibling
假设,此处相同:目的地出现在起点之后。
let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return (
$origin,
$origin/following-sibling::leg[. << $dest],
$dest
)
使用节点比较
假设,此处相同:目的地出现在起点之后。
let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return $JOURNEY/leg[
. is $origin or
. >> $origin and . << $dest or
. is $dest
]
递归方法
假设:无法保证订单。
declare function local:trace(
$leg as element(leg),
$journey as element(journey),
$end as xs:string
) as element(leg)* {
$leg,
for $dest in $leg/@dest[. != $end]
return local:trace($journey/leg[@origin = $dest], $journey, $end)
};
local:trace($JOURNEY/leg[@origin = $ORIGIN], $JOURNEY, $DEST)
我有以下xml数据结构
<journey>
<leg origin='a' dest='b' />
<leg origin='b' dest='c' />
<leg origin='c' dest='d' />
<leg origin='d' dest='e' />
<leg origin='e' dest='f' />
... and so on
</journey>
我想 select leg
从 origin='b'
到 dest='e'
我试过使用翻滚 window, following-sibling,但似乎只能匹配第一个和最后一个元素,中间没有任何元素。
我在 BaseX 8.6 中使用 XQuery 3.0
由于最初的问题并未给出所有范围条件,因此我提供了几个答案。所有这些都基于相同的查询序言和以下假设(可能还有其他假设):
- 搜索到的出发地和目的地存在
- 所有起点和终点只出现一次
- 没有循环(例如
b
→c
→b
)
查询序言
declare variable $JOURNEY :=
<journey>
<leg origin='a' dest='b' />
<leg origin='b' dest='c' />
<leg origin='c' dest='d' />
<leg origin='d' dest='e' />
<leg origin='e' dest='f' />
</journey>;
declare variable $ORIGIN := 'b';
declare variable $DEST := 'e';
使用翻滚window
假设:目的地出现在起点之后。
for tumbling window $legs in $JOURNEY/leg
start $s when $s/@origin = $ORIGIN
end $e when $e/@dest = $DEST
return $legs
使用following-sibling
假设,此处相同:目的地出现在起点之后。
let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return (
$origin,
$origin/following-sibling::leg[. << $dest],
$dest
)
使用节点比较
假设,此处相同:目的地出现在起点之后。
let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return $JOURNEY/leg[
. is $origin or
. >> $origin and . << $dest or
. is $dest
]
递归方法
假设:无法保证订单。
declare function local:trace(
$leg as element(leg),
$journey as element(journey),
$end as xs:string
) as element(leg)* {
$leg,
for $dest in $leg/@dest[. != $end]
return local:trace($journey/leg[@origin = $dest], $journey, $end)
};
local:trace($JOURNEY/leg[@origin = $ORIGIN], $JOURNEY, $DEST)