我试图递归地生成一个在星期一数据库中彼此相邻的国家的XML文档。该文件应说明到达该国您需要越过多少个边界以及越过的国家总数。
XML应该如下所示:
<from_swe_cross>
<cross num="1" sum="2">
<country>Finland</country>
<country>Norway</country>
</cross>
<cross num="2" sum="3">
<country>Russia</country>
</cross>
我知道如何生成可以访问的国家/地区列表,但不知道如何正确设置其格式,也不知道已经制作了多少个跨境或穿越的国家总数。
我的代码现在是:
declare function local:crossing($stack, $seen, $level, $sum) {
if(empty($stack)) then $seen
else (
let $country := $stack[1]
let $neighbors :=
for $code in $country/border/@country[not(. = $seen/@car_code)]
return $country/../country[@car_code = $code]
return local:crossing(($neighbors, $stack[position() > 1]), ($seen, $neighbors), $level + 1, $sum + count($neighbors))
)
};
<from_swe_cross>{
local:crossing(db:open('mondial')//country[@car_code = 'S'], db:open('mondial')//country[@car_code = 'S'], 1, 0)/name
}
</from_swe_cross>
但这仅列出了您可以跨越的所有国家,例如:
<from_swe_cross>
<name>Albania</name>
<name>Greece</name>
<name>Macedonia</name>
<name>Serbia</name>
<name>Montenegro</name>
...
</from_swe_cross>
如何生成正确的XML?
答案 0 :(得分:0)
一种解决方案是使用一个累加参数,在该参数中您从空序列开始收集结果序列:
declare function local:crossing($stack, $seen, $level, $sum, $out) {
if(empty($stack)) then $out
else (
let $country := $stack[1]
let $neighbors :=
for $code in $country/border/@country[not(. = $seen/@car_code)]
return $country/../country[@car_code = $code]
let $sum := $sum + count($neighbors)
return local:crossing(
($neighbors, $stack[position() > 1]),
($seen, $neighbors),
$level + 1,
$sum,
($out, <cross num="{$level}" sum="{$sum}">{$neighbors/name}</cross>)
)
)
};
<from_swe_cross>{
local:crossing(
db:open('mondial')//country[@car_code = 'S'],
db:open('mondial')//country[@car_code = 'S'],
1, 0, ()
)
}
</from_swe_cross>
结果看起来就像上面的显示:
<from_swe_cross>
<cross num="1" sum="2">
<name>Finland</name>
<name>Norway</name>
</cross>
<cross num="2" sum="3">
<name>Russia</name>
</cross>
<cross num="3" sum="15">
<name>Belarus</name>
<name>Latvia</name>
<name>Lithuania</name>
<name>Poland</name>
<name>Ukraine</name>
<name>Estonia</name>
<name>China</name>
...
找不到新目的地的步骤显示为空的cross
元素。如果您愿意,您可以压制那些。
...
<cross num="4" sum="15"/>
<cross num="5" sum="15"/>
<cross num="6" sum="15"/>
<cross num="7" sum="18">
<name>Czech Republic</name>
<name>Germany</name>
<name>Slovakia</name>
</cross>
...