0

我有多个员工 xml 文档使用 doc uri (/employee/*.xml) 保存在 ML DB 中,我想从新 XML 中获取更新,其中唯一引用键是 roleID(在 ML XML 中它的 roleID 和在新 XML 中它是 newroleID )。每当找到匹配项时,它应该用新的 XMl 的 newFirstName 更新 ML xml 的 firstName 值,用 newlastName 更新 lastname 值,用新的 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>
4

2 回答 2

3

请参阅xdmp:node-replace

从文档示例中:

(: 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>
于 2012-08-01T19:55:06.300 回答
1

表达式doc("/employee/*.xml")不起作用。使用xdmp:directorywill,前提是创建目录(自动或手动)。或者,如果启用了 URI 词典,您可以使用它cts:uri-match来查找员工的 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 完全替换它。无论如何,该文档完全在幕后替换,因此您几乎不会注意到与如此小的文档有任何区别。

于 2012-08-01T20:23:30.903 回答