使用XQuery进行递归并举例说明
我有一个类似这样的数据库(通过使用XQuery进行递归并举例说明,xquery,Xquery,我有一个类似这样的数据库(通过$database访问它): 对该函数的调用: local:reachable($database/country[@car_code = "F"]) 与法国接壤的国家应为: <border country="AND" length="60"/> <border country="E" length="623"/> <border country="D" length="451"/> <border cou
$database
访问它):
对该函数的调用:
local:reachable($database/country[@car_code = "F"])
与法国接壤的国家应为:
<border country="AND" length="60"/>
<border country="E" length="623"/>
<border country="D" length="451"/>
<border country="I" length="488"/>
<border country="CH" length="573"/>
<border country="B" length="620"/>
<border country="L" length="73"/>
<border country="MC" length="4.4"/>
但我们也需要为这些国家找到边界国家。
最终输出应为“F”、“和”、“E”、“D”、“I”、“CH”、“B”、“L”、“MC”…、X、Y、Z(以及与这些国家接壤的其他国家)
- 我知道联盟没有定义,但还有什么我可以使用的吗?我只是想更清楚地知道我想做什么
- 除了语法错误之外,还有一个大问题,那就是如果“F”与“L”相邻,那么“L”将与“F”相邻,所以我的“函数”永远不会终止——我该如何处理
- 我能得到一些语法方面的帮助吗
- 如果问题不清楚,请让我知道,以便我进一步澄清
定义一个变量,该变量必须包含 只有一个元素,所以它永远不能为空;如果需要,请使用$country as element()
元素是可选的,element()?
如果可以有任意数量的 它们,或者如果必须有一个或多个元素,则为element()*
element()+
- 序列运算符
可用于从 其他序列:,
构造2个序列:(1,2)、(3,4)
和(1,2)
,然后构造另一个包含 其他,导致:(3,4)
(1,2,3,4)
countries
元素,以便消除噪声,
让这个演示变得简单一点。此外,我还创建了一个
简单但完整的地图。让我们假设我们有两个相邻的国家
K和其他4个组成正方形(每个国家相邻2个)
其他):N、G、B和F。与现有地理或
政治只在你眼中:-)
夸张的
遥不可及
平地
马霍姆
蜂房
葡萄饼
解决方案
该解决方案包括一个递归函数,该函数使用
需要处理的国家。同时,它将结果列表累加为1
一次一个国家。它取队列中的第一个国家,将其添加到
然后,结果会在所有不受影响的邻国重现
已在队列中,也不是当前结果。扩大的结果是
也传下来了
xquery version "3.0";
declare variable $countries :=
<countries>
<!-- as above, just copy and paste it -->
</countries>;
declare function local:reachable(
$queue as element(country)*,
$result as element(country)*
) as element(country)*
{
if ( empty($queue) ) then (
(: we do not consider one country reachable from itself :)
tail($result)
)
else (
let $this := head($queue)
let $rest := tail($queue)
let $more := $this/border/@idref[not(. = ($queue, $result)/@id)]
return
local:reachable(
( $rest, $countries/country[@id = $more] ),
( $result, $this ))
)
};
(: for each countries, display its reachable countries
:)
for $c in $countries/country
order by $c/@id
let $r := local:reachable($c, ())
return
$c/name || ': ' || string-join($r/@id, ', ')
这给了我很多的快乐-很好!您的评论也是:-)
<border country="AND" length="60"/>
<border country="E" length="623"/>
<border country="D" length="451"/>
<border country="I" length="488"/>
<border country="CH" length="573"/>
<border country="B" length="620"/>
<border country="L" length="73"/>
<border country="MC" length="4.4"/>
xquery version "3.0";
declare variable $countries :=
<countries>
<!-- as above, just copy and paste it -->
</countries>;
declare function local:reachable(
$queue as element(country)*,
$result as element(country)*
) as element(country)*
{
if ( empty($queue) ) then (
(: we do not consider one country reachable from itself :)
tail($result)
)
else (
let $this := head($queue)
let $rest := tail($queue)
let $more := $this/border/@idref[not(. = ($queue, $result)/@id)]
return
local:reachable(
( $rest, $countries/country[@id = $more] ),
( $result, $this ))
)
};
(: for each countries, display its reachable countries
:)
for $c in $countries/country
order by $c/@id
let $r := local:reachable($c, ())
return
$c/name || ': ' || string-join($r/@id, ', ')
Beerium: N, G, F
Grapeandcheese: N, G, B
Marxhome: N, B, F
Beyond the see: U
Flatland: G, B, F
Over the top: K