草庐IT

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

coder 2024-06-26 原文

我正在尝试制作一种算法,该算法在 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/

有关xml - 在 XQuery 中搜索两个图形节点之间的路径的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  4. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  6. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  7. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  8. ruby-on-rails - Rails - 使用/自定义 URL : '/dashboard' 指定根路径 - 2

    如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b

  9. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  10. ruby-on-rails - 使用作为方法的值在 ruby​​ 中搜索哈希 - 2

    我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod

随机推荐