2013-09-04 11 views
5

Sto provando a modificare il valore di diversi nodi in un file XML molto grande caricato in memoria da un modulo Web.Modifica il valore XML in memoria con xQuery

Il file si ottiene in questo modo:

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

Quindi, come si può vedere il file è in memoria.

Ora, ho bisogno di cambiare il valore di migliaia di nodi, e finora non sono stato in grado di farlo in modo ottimale.

Qualche idea?

Alcune delle cose che ho tryied finora:

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 
     (

     ) 

La biblioteca Mem è un'usanza scaricato uno.

risposta

4

Se possibile, inserire il documento nel database e in una transazione separata aggiornare i nodi utilizzando 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) }); 

In alternativa, se è necessario aggiornare il documento in memoria, è probabilmente più ottimale camminare l'albero solo una volta (facendo gli aggiornamenti tutti in quell'operazione), piuttosto che multiplo mem:replace operazioni (che probabilmente ogni ri- cammina l'albero).

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) 
... 

Aggiornamento:

Come Erik suggerisce nei commenti, potete anche scrivere la logica di local:update-ids a XSLT (utilizzando xdmp:xslt-eval o xdmp:xslt-invoke per l'esecuzione), e dovrebbero essere più o meno equivalente, in termini di prestazione. In realtà, Mark Logic ha un blog molto ben scritto sul tema:

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

+3

Per completezza, una terza alternativa è di applicare una trasformazione XSLT al documento in memoria. – ehennum

Problemi correlati