微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用xQuery更改内存中的XML值

我正在尝试从Web表单中更改内存中加载的非常大的 XML文件中的几个节点的值.

文件是这样获得的:

let $file := xdmp:get-request-field("xml_to_upload")

所以,你可以看到文件在内存中.

现在,我需要更改数千个节点的值,到目前为止,我还没能以最佳方式完成它.

有任何想法吗?

到目前为止我尝试过的一些事情:

let $auxVar :=
        if($fileStructureIsValid) then
        (
            for $currentNode in xdmp:unquote($file)//ID

            let $log := xdmp:log( fn:concat( "newNodeValue",": ",mem:replace( $currentNode,element ID{ fn:concat( $subject,"-",fn:data( $currentNode ) ) } ) ) )

                return fn:concat( $subject,fn:data( $currentNode ) )
        )
        else
        (

        )

mem库是一个自定义下载的库.

如果可能,将文档插入数据库,并在单独的事务中使用xdmp:node-replace更新节点.
xquery version "1.0-ml";
...
xdmp:document-insert('file.xml',$file) ;

xquery version "1.0-ml";

for $currentNode in doc('file.xml')//ID
return xdmp:node-replace($currentNode,element ID{ concat($subject,$currentNode) });

或者,如果你必须在内存中更新文档,那么最好只在树上行走一次(在该操作中进行所有更新),而不是多个mem:replace操作(可能每次重新遍历树).

declare function local:update-ids(
  $n as item(),$subject as xs:string
) as item()
{
  typeswitch ($n)
    case element(ID) return 
      element ID { concat($subject,$n) }
    case element() return
      element { node-name($n) } {
        @*,$n/node()/local:update-ids(.,$subject) }
    default return $n
};

let $xml := xdmp:unquote($file)
let $xml-with-updated-ids := local:update-ids($xml,$subject)
...

更新:

正如Erik在评论中建议的那样,您还可以在XSLT中编写local:update-ids的逻辑(使用xdmp:xslt-eval或xdmp:xslt-invoke来执行),并且它们在性能方面应该大致相同.实际上,MarkLogic在这主题上有一篇写得很好的博客文章

http://developer.marklogic.com/blog/tired-of-typeswitch

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。