la actualización de múltiples nodos en XML con xquery y xdmp: nodo-reemplazar

StackOverflow https://stackoverflow.com/questions/4510465

  •  12-10-2019
  •  | 
  •  

Pregunta

Quiero actualizar un documento XML en mi base de datos XML (MarkLogic). Tengo XML como entrada y quiero reemplazar cada nodo que existe en el XML de destino.

Si un nodo no existe sería grande si se agrega, pero eso es quizá otra tarea.

Mi XML en la base de datos:

<user>
  <username>username</username>
  <firstname>firstname</firstname>
  <lastname>lastname</lastname>
  <email>email@mail.de</email>
  <comment>comment</comment>
</user>

El valor de $ user_xml:

<user>
  <firstname>new firstname</firstname>
  <lastname>new lastname</lastname>
</user>

Mi función hasta ahora:

declare function update-user (
    $username as xs:string,
    $user_xml as node()) as empty-sequence()
{
    let $uri := user-uri($username)
    return
        for $node in $user_xml/user
        return 
            xdmp:node-replace(fn:doc($uri)/user/fn:node-name($node), $node)
};

En primer lugar no puedo iterar sobre $user_xml/user. Si trato de iterar sobre $user_xml consigo la excepción

arg1 no es de tipo nodo ()

Pero tal vez es el enfoque equivocado de todos modos?

¿Alguien tiene quizá código de ejemplo de cómo hacer esto?

¿Fue útil?

Solución

Tengo que responder a mí mismo:

declare function update-user (
$username as xs:string,
$user_xml as node()) as empty-sequence()
{
let $uri := user-uri($username)
return
    for $node in $user_xml/*
    let $target := fn:doc($uri)/user/*[fn:name() = fn:name($node)]
    return
        if($target) then
            xdmp:node-replace($target, $node)
        else
            xdmp:node-insert-child(fn:doc($uri)/user, $node)
};

pero tal vez alguien tiene una mejor solución a /user/*[fn:name() = fn:name($node)]?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top