【问题标题】:run xpath from xquery against a database?从 xquery 对数据库运行 xpath?
【发布时间】:2019-01-01 13:14:23
【问题描述】:

如何使用basex GUI 从xquery 脚本中运行xpath 查询?

成功xpath 查询数据库:

xquery 尝试失败:

此数据库最简单的xquery 代码:

thufir@dur:~/basex$ 
thufir@dur:~/basex$ cat db_list_items.xq 

let $db := db:open("list")

return root()/descendant::li/a/text()

thufir@dur:~/basex$ 

不太清楚如何返回上面的结果。

来自basex GUI 的错误日志:

Error:
Stopped at /home/thufir/basex/db_list_items.xq, 4/12:
[XPDY0002] root(): no context value bound.
Compiling:
- pre-evaluate db:open(database[,path]) to document-node(): db:open("list") -> db:open-pre("list", 0)
- inline $db_0
- simplify gflwor
Optimized Query:
root()/descendant::li/a/text()
Query:
let $db := db:open("list") return root()/descendant::li/a/text()
Query plan:
<QueryPlan compiled="true" updating="false">
  <CachedPath type="text()*">
    <FnRoot name="root([node])" type="node()?"/>
    <IterStep axis="descendant" test="li" type="element()*"/>
    <IterStep axis="child" test="a" type="element()*"/>
    <IterStep axis="child" test="text()" type="text()*"/>
  </CachedPath>
</QueryPlan>

使用 basex 查找此数据库的简单查询。

【问题讨论】:

    标签: xml xpath xml-parsing xquery basex


    【解决方案1】:

    就像导航文件系统(或任何其他基于树的结构)一样,我们需要知道我们在该结构中的位置,以便能够使用路径表达式:

    /home/logname/documents/work #> cd todo
    /home/logname/documents/work/todo #>
    

    命令行解释器是怎么知道的,在哪里可以找到 todo 目录?它知道这一点,因为按照惯例,它假定cd 命令的上下文是当前目录,在本例中为/home/logname/documents/work

    当您将文档/数据库加载到 BaseX 中时,它对 XPath 表达式和 XQuery 执行相同的操作,只要上下文是明确的。例如,如果您在查询编辑器中放置一个点 .,然后执行该查询,它将返回整个文档,因为这就是 . 所代表的:当前上下文项。在这里,BaseX 从约定中知道这个上下文,默认情况下,它对当前加载的文档执行查询,就像命令行解释器将当前目录假定为当前上下文一样。可以说,通过加载文档/数据库,您cd'ed 进入了该文档的根目录。到目前为止一切顺利...

    一旦您使用 XQuery,您就是在使用一种完整的编程语言,它允许的功能远不止查询单个文档。您可以在一个脚本中查询一大堆文档。

    获取这个(不完整的)代码片段:

    let $db  := db:open("list")
    let $db2 := db:open("list2")
    

    如果您现在按照以前的方式进行查询,它们会去哪里?他们是使用$db 作为上下文还是$db2

    你需要做的是告诉处理器这件事。这可以通过多种方式完成:

    1. 在 XPath 表达式本身中:
    let $db := db:open("list")
    return $db/root()/descendant::li/a/text()
    

    或者,简化:

    let $db := db:open("list")
    return $db//li/a/text()
    

    或:

    declare context item := db:open("list");
    
    .//li/a/text()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多