我在ML DB中使用doc uri(/employee/*.xml)保存了多个员工xml文档,我想从新XML获取更新,其中唯一引用键是roleID(在ML XML中,其roleID和新XML)它是newroleID)。每当找到匹配时,它应该使用新的XMl的newFirstName更新ML xml的firstName值,使用newlastName更新lastname值,使用new dep更新dep,并且xml结构的其余部分保持相同。
Marklogic XML结构如下:
doc uri /employee/1.xml
<employee>
<firstName>Jim</firstName>
<lastName>Day</lastName>
<dep>IT</dep>
<city>Boston</city>
<roleID>1111<roleID>
<internalID>2222</internalID>
</employee>
doc uri /employee/2.xml
<employee>
<firstName>Jan</firstName>
<lastName>Silly</lastName>
<dep>Finance</dep>
<city>DC</city>
<roleID>3333<roleID>
<internalID>4444</internalID>
</employee>
doc uri /employee/3.xml
<employee>
<firstName>Jack</firstName>
<lastName>John</lastName>
<dep>HR</dep>
<city>Virginia</city>
<roleID>5555<roleID>
<internalID>6666</internalID>
</employee>
我正在尝试这个但不确定如何更新文档,它也似乎是优化的xquery,请帮助。
let $newXML := <employees>
<newemployee>
<NewfirstName>New Fname1</newfirstName>
<newlastName>New Lname1</newlastName>
<newdep>New Dep1</newdep>
<newcity>Boston</newcity>
<newroleID>1111<newroleID>
<internalID>2222</internalID>
</newemployee>
<newemployee>
<newfirstName>New Fname2</newfirstName>
<newlastName>New Lname</newlastName>
<newdep>New Dep</newdep>
<newcity>Boston</newcity>
<newroleID>5555<newroleID>
<newinternalID>6666</newinternalID>
</employee>
</employees>
for $oldXML in doc("/employee/*.xml")/employee
where $newXML/newemployee/newroleID eq $oldXML/roleID
return
for $Matched in $oldXML
return
let $finalXML :=
(: Not sure how to update some nodes in given URI, where rest of structure remain same :)
<employee>
<firstName>{$newXML/newemployee/newfirstName/text()}</firstName>
<lastName>{$newXML/newemployee/newlastName/text()}</lastName>
<dep>{$newXML/newemployee/newdep/text()}</dep>
</employee>
答案 0 :(得分:3)
来自文档示例:
(: insert the doc :)
xdmp:document-insert("/example.xml", <a><b>bbb</b></a>);
(: replace the b node in the doc with this c node :)
xdmp:node-replace(doc("/example.xml")/a/b, <c>ccc</c>);
doc("/example.xml") => <a><c>ccc</c></a>
答案 1 :(得分:1)
表达式doc("/employee/*.xml")
不起作用。如果创建目录(自动或手动),则使用xdmp:directory
。或者,您可以使用cts:uri-match
为员工查找uris,如果启用了URI词典,则可以将这些内容传递给doc()
。
但是......你方法中最大的瓶颈就是遍历所有文件。这不是必要的。如果roleID是唯一的,那么将其用于uri,这样您就不需要遍历所有文档,只需立即打开正确的文档即可。或者,使用可由XQuery处理器优化的表达式,或者仅依赖于索引。如下所示:
doc()[//roleID = $newRoleID]
或者:
cts:search(doc(), cts:element-value-query(xs:QName("roleID"), $newRoleID))
对于更新本身,您可以使用xdmp:node-replace
和@sgarrett建议的相关,但您也可以简单地重新创建整个XML,并使用xdmp:document-insert完全替换它。无论如何,文件完全替换在场景后面,所以你几乎不会注意到这些小文件的任何差异。
HTH!