从xquery对数据库运行xpath?

时间:2019-01-01 13:14:23

标签: xml xpath xml-parsing xquery basex

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

成功xpath查询数据库: xpath

失败的xquery尝试: 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查找此数据库的简单查询。

1 个答案:

答案 0 :(得分:1)

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

<?php
    $doc = new DOMDocument();

    @$doc->loadHTMLFile('https://amazon.com/dp/' . $_GET['asin']);

    $xpath = new DOMXPath($doc);
    $title = $xpath->evaluate('//*[@id="productTitle"]');
    $title = trim($title[0]->nodeValue);

    $image = $xpath->evaluate('//*[@id="landingImage"]');
    $image = trim($image[0]->getAttribute('src'));

    $buybox = $xpath->evaluate('//*[@id="price_inside_buybox"]');
    $buybox = trim($buybox[0]->nodeValue);

    die(json_encode([
      'asin'        => $_GET['asin'],
      'title'       => $title,
      'buybox'      => str_replace('$', '', $buybox),
      'image'       => "<img src=\"" . $image . "\" />",
    ]));

命令行解释器如何知道在哪里找到 todo 目录?之所以知道这一点,是因为按照惯例,它假设/home/logname/documents/work #> cd todo /home/logname/documents/work/todo #> 命令的上下文是当前目录,在这种情况下为cd

在将文档/数据库加载到BaseX中时,只要上下文清晰即可,它对XPath表达式以及XQuery都执行相同的操作。例如,如果您在查询编辑器中放置一个点/home/logname/documents/work,然后执行该查询,它将返回整个文档,因为这是.的意思:当前上下文项。在这里,BaseX从约定中了解了此上下文,默认情况下,它会针对当前加载的文档执行查询,就像命令行解释器假定当前目录为当前上下文一样。可以说,通过加载文档/数据库,您.进入了该文档的根目录。到目前为止一切顺利...

使用XQuery时,您正在使用的是一种完整的编程语言,它不仅可以查询单个文档,还可以提供更多功能。您可以在一个脚本中查询一堆文件。

获取以下(不完整的)代码片段:

cd

如果您现在按照自己的方式放置查询,它们会去哪里?他们是使用let $db := db:open("list") let $db2 := db:open("list2") 作为上下文还是$db

您需要做的是告诉处理器有关此问题。这可以通过几种方法完成:

  1. 在脚本的序言中:$db2(另请参见:BaseX documentation on this,非常重要的是read about the difference between "static context" and "dynamic context" here),以了解有关上下文的更多信息。
  2. 在XPath表达式本身中:
declare context item := db:open("list");

或者,简化:

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

或:

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