【问题标题】:How to dynamically reference nodes in xdmp:node-replace in MarkLogic?如何在 MarkLogic 中动态引用 xdmp:node-replace 中的节点?
【发布时间】:2013-07-02 08:12:28
【问题描述】:

在我的函数 update-replace 中,我试图通过调用 xdmp:node-replace 来动态替换 MarkLogic 中我的 XML 数据源文件之一中的 XML 节点,如下所示:

declare function update-lib:update-rec($doc as xs:string, $path as xs:string, $country as xs:string, $name as xs:string, $population as xs:integer, $latitude as xs:decimal, $longitude as xs:decimal) as document-node() {
    (: read lock acquired :)
    fn:doc($doc),

    xdmp:node-replace(fn:doc($doc)/$path,
        <city>
            <country>{$country}</country>
            <name>{$name}</name>
            <population>{$population}</population>
            <latitude>{$latitude}</latitude>
            <longitude>{$longitude}</longitude>
        </city>
    ),


    (: after the following statement, txn ends and locks released :)
    xdmp:commit()
};

该函数有 7 个参数,第一个参数是 XML 源文件的路径,第二个参数是 XML 文件中要更新的节点的路径,其余的对应于子元素值。

当我调用xdmp:node-replace更新数据时,遇到如下错误:

500 内部服务器错误

XDMP-ARGTYPE: (err:XPTY0004) xdmp:node-replace("/cities/city[3961]", JPMiyoshi56958) -- arg1 不是 node() 类型 ...

所以我决定评估 arg1 以确保 node() 作为 node-replace 的第一个 arg 传递:

xdmp:node-replace(xdmp:eval(fn:doc($doc)/$path),
    <city>
        <country>{$country}</country>
        <name>{$name}</name>
        <population>{$population}</population>
        <latitude>{$latitude}</latitude>
        <longitude>{$longitude}</longitude>
    </city>
),

现在我收到以下错误:

XDMP-UPEXTNODES: xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_02.xml")/cities/city[3961], JPMiyoshi56958) -- 无法更新外部节点...

经过一番谷歌搜索,我找到了这个。这听起来像是xdmp:eval 及其上下文的问题:

http://developer.marklogic.com/pipermail/general/2008-September/001753.html

我尝试了此处建议的解决方法,使用 fn:concat 将所有内容构造为字符串,包括 xdmp:node-replace 并评估整个语句。

xdmp:eval(fn:concat('xdmp:node-replace(fn:doc("', $doc, '")', $path,
    ', ', '<city><country>',$country,'</country><name>',$name,'</name><population>',$population,'</population><latitude>',$latitude,'</latitude><longitude>',$longitude,'</longitude></city>', ')')),

当我尝试这个时,应用程序在超时之前等待了很长时间。 500 内部服务器错误

SVC-EXTIME: xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_17.xml")/cities/city[3961], JPMiyoshi56958) -- 超过时间限制...

我要做的就是动态引用 XML 文件和要更新的节点,并使用传入的信息更新节点。我一定是忽略了一些非常基本的东西,或者这样做是完全错误的。

有人可以解释一下吗?

【问题讨论】:

  • 您尝试 xdmp:unpath() 与您的第一个脚本,第二个参数参数 - $path 将字符串评估为 XPath 并返回相应的节点。您可以在docs.marklogic.com/xdmp:unpath 找到更多信息
  • 这实际上也很有效。谢谢!

标签: xquery marklogic


【解决方案1】:

在您的第一个解决方案中,您将字符串值应用于fn:doc($doc) 返回的每个文档节点。这样,您最终只会得到 $xpath 本身的字符串值。第二种解决方案也有效地采用了 $xpath 的值,并尝试对其进行评估。这很可能会产生很多可能都被更新的节点。

我不完全确定您为什么会收到 XDMP-UPEXTNODES 和超时,但以下应该可以......

替换:

fn:doc($doc)/$path

与:

xdmp:value(fn:concat("fn:doc($doc)", $path))

HTH!

【讨论】:

  • 工作就像一个魅力!谢谢!
猜你喜欢
  • 2020-11-09
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多