gpt4 book ai didi

xml - 在 XQuery 中搜索两个图形节点之间的路径

转载 作者:数据小太阳 更新时间:2023-10-29 01:56:30 29 4
gpt4 key购买 nike

我正在尝试制作一种算法,该算法在 xQuery 中的图形中搜索并返回两个节点之间的路径,到目前为止我运气不好,因为它只返回一个节点并且它是相邻节点。首先我要明确的是,该图是一个有向图,每个节点都可以有零个、一个或多个起点,在 XML 中,一个节点只有指向它的起点的链接,但没有指向它的后续节点的链接 < br/>

这是一些节点及其 XML 的示例

<node>
<id> 123-456-789</id>
<name> something </name>
<Links>
<Link>
<origin></origin>
</Link>
<Links>

<node>
<id> 245-678-901</id>
<name> node 2</name>
<Links>
<Link>
<origin> 123-456-789 </origin>
</Link>
<Links>

<node>
<id> xxx-xxx-xxx</id>
<name> node 3</name>
<Links>
<Link>
<origin> 123-456-789 </origin>
</Link>
<Links>

<node>
<id> 234-546-768</id>
<name> node 4</name>
<Links>
<Link>
<origin> 245-678-901</origin>
</Link>
<Links>

我想从那个 XML 中获取从节点 1 到节点 4 的路径(node1-> node2 -> node4)但无论我尝试做什么,只会给我 node1-node2 和 node3 而不是 node4另一件事是我想选择一条不直接的路径,我的意思是,如果我想要 node5 和 node7 之间的路径,但 node5 和 node7 都指向 node6

我已经尝试将此 python 代码改编为 xquery

def BFS(graph,start,end,q):

temp_path = [start]

q.enqueue(temp_path)

while q.IsEmpty() == False:
tmp_path = q.dequeue()
last_node = tmp_path[len(tmp_path)-1]
print tmp_path
if last_node == end:
print "VALID_PATH : ",tmp_path
for link_node in graph[last_node]:
if link_node not in tmp_path:
new_path = []
new_path = tmp_path + [link_node]
q.enqueue(new_path)

(代码不是我的,它属于 this activestate page 的合法编码员)

这是我尝试过的:

declare function local:BFS($graph as element()* , $ini_node as element(Node)*, $end_node as element(Node)*) as element()*
{
let $seq := $ini_node
let $queue := ($seq)
for $item in $queue
return
if ( count($queue) > 0) then
let $seq := remove($queue, count($queue))
let $last := $seq[last()] return if (deep-equal($last, $end_node)) then $seq
else
for $node in $graph[contains(.,$graph/id[contains(.,$last/Links/Link/origin/text())])] (: what i've tried was to get the graph nodes which id is equal to the origins of the last node :)
return if(not(functx:is-node-in-sequence-deep-equal($node,$seq))) then
let $new_path:= ()
let $new_path:= insert-before($seq, count($seq)+1, $node)
let $queue := insert-before($queue,1, $new_path) return $queue
else ()

else
()


};

最佳答案

XQuery 和 Python 的根本区别在于 XQuery 是一个 functional programming language .这意味着绑定(bind)到变量的值之后无法修改。例如,在您的函数 local:BFS(...) 中,您不能在循环内更改 $queue 的值,您所做的就是创建一个新变量 隐藏外部队列的 $queue

为了让它工作,你可以把外层循环写成recursive function相反,它将当前队列作为参数。循环的每次迭代都是使用更新版本的队列调用函数:

declare function local:BFS($graph, $queue, $steps, $end) {
if(empty($queue)) then error(xs:QName('local:NOTFOUND'), 'No path found.')
else (
let $curr := $queue[1], $rest-queue := $queue[position() > 1]
return (
if($curr eq $end) then local:result($steps, $end)
else (
let $successors :=
$graph//node[Links/Link/origin = $curr and not($steps/@to = id)]/id/string()
let $new-steps :=
for $succ in $successors
return <edge from="{$curr}" to="{$succ}" />
return local:BFS(
$graph,
($rest-queue, $successors),
($steps, $new-steps),
$end
)
)
)
)
};

可以通过将第一条边提供给起始节点来调用它:

declare function local:BFS($graph, $start, $end) {
local:BFS($graph, $start, <edge to="{$start}" />, $end)
};

所有使用的边都存储在 $steps 中。为了在找到目的地后重建路径,我们可以向后遍历它们直到找到初始边:

declare function local:result($steps, $dest) {
let $pred := $steps[@to = $dest]/@from/string()
return if(exists($pred)) then (local:result($steps, $pred), $dest)
else $dest
};

如果您关心性能,XQuery 序列可能不是用作队列的最佳数据结构。用于查找的 XML 片段也是如此。因此,如果您有权访问 XQuery 3.0处理器,你可以看看我在 https://github.com/LeoWoerteler/xq-modules 上写的一些(至少渐进地)更高效的数据结构。 .我什至包括了Dijkstra's algorithm举个例子。

关于xml - 在 XQuery 中搜索两个图形节点之间的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23194711/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com