Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
BaseX—在XQuery中使用封闭xml时内存不足_Xquery_Basex - Fatal编程技术网

BaseX—在XQuery中使用封闭xml时内存不足

BaseX—在XQuery中使用封闭xml时内存不足,xquery,basex,Xquery,Basex,我一直在尝试查询一个包含超过1500000项的BaseX数据库。 当我运行此查询时 for $item in collection('coll')//item return $item (: returns an xml element :) 它在不到一秒钟的时间内执行 但是,当我尝试以xml形式返回结果时,会出现“内存不足”错误 { 对于集合('coll')//项中的$item 退货$item } 这让我想放弃原生XMLDB方法(其他数据库也会如此,比如eXistDB),因此如果有

我一直在尝试查询一个包含超过1500000项的BaseX数据库。 当我运行此查询时

for $item in collection('coll')//item
    return $item (: returns an xml element :)
它在不到一秒钟的时间内执行

但是,当我尝试以xml形式返回结果时,会出现“内存不足”错误

{
对于集合('coll')//项中的$item
退货$item
}
这让我想放弃原生XMLDB方法(其他数据库也会如此,比如eXistDB),因此如果有人知道这个问题,这将非常有帮助


感谢

由于XQuery的语义,如果所有子节点都由新的父节点包装,则需要复制它们。下面的查询演示了这一点,它比较了原始节点和复制节点的节点标识。它将产生
false

let $node := <node/>
let $parent := <parent>{ $node }</parent>
return $parent/node is $node
let$node:=
让$parent:={$node}
返回$parent/node为$node
由于复制数百万个节点的成本很高,因此不可避免地会导致内存不足错误

<xml>{
    for $item in collection('coll')//item
       return $item
}</xml>
如果将结果写入文件,这里有一个实用的解决方案可以绕过此限制:

(:~ 
 : Writes element to a file, wrapped by a root node.
 : @param  $path      path to file
 : @param  $elements  elements to write
 : @param  $name      name of root node
 :)
declare function local:write-to(
  $path      as xs:string,
  $elements  as element()*,
  $name      as xs:string
) as empty-sequence() {
  file:write-text($path, '<' || $name || '>'),
  file:append($path, $elements),
  file:append-text($path, '</' || $name || '>')
};

local:write-to('result.xml', <result/>, 'root')
(:~
:将元素写入由根节点包装的文件。
:@param$path文件的路径
:@param$elements要写入的元素
:@param$name根节点的名称
:)
声明函数本地:写入(
$path作为xs:string,
$elements作为element()*,
$name作为xs:string
)作为空-sequence(){
文件:写入文本($path',),
文件:追加($path,$elements),
文件:追加文本($path“”)
};
本地:写入('result.xml','root')

预测批评:这是一个明显的攻击。例如,该方法与BaseX的各种非默认序列化参数冲突(如果需要输出XML声明等,则结果的格式将不正确)。

对于BaseX 9.0,您可以通过以下选项暂时禁用节点复制:

(#db:copynode false#){
{
对于集合('coll')//项中的$item
退货$item
}
}

从未想过在这种情况下会复制节点。。。这就解释了。我会试试你的建议,然后回来发表评论。非常感谢你!在这种情况下,“临时”意味着什么?临时应该是指»在pragma«的范围内。如果这与原始的效果相同,即返回包装的节点,我想知道为什么这不是默认行为,因为它不消耗资源……pragma绕过了XQuery规范的语义,因此,它被作为可选功能引入。例如:
let$x:=return(#db:copynode false#){{$x}/x是$x}
生成true;如果没有pragma,它将产生false。
(# db:copynode false #) {
  <xml>{
    for $item in collection('coll')//item
    return $item
  }</xml>
}