2013-09-04 13 views
5

Próbuję zmienić wartość kilku węzłów w bardzo dużym pliku XML załadowanym do pamięci z formularza internetowego.Zmień wartość XML w pamięci za pomocą xQuery

Plik uzyskuje się w ten sposób:

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

Więc, jak widać plik znajduje się w pamięci.

Teraz potrzebuję zmienić wartość tysięcy węzłów, i jak dotąd nie byłem w stanie zrobić tego w optymalny sposób.

Wszelkie pomysły?

Niektóre rzeczy mam tryied tej pory:

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 
     (

     ) 

Biblioteka mem jest zwyczaj pobrać jeden.

Odpowiedz

4

Jeśli to możliwe, włóż dokument do bazy danych, aw oddzielnej aktualizacji transakcji węzły używają 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) }); 

Ewentualnie, jeśli masz do aktualizacji dokumentu w pamięci, to prawdopodobnie bardziej optymalne spacery z drzewa tylko raz (dokonywania aktualizacji wszystkie w tej operacji), a nie wielokrotność mem:replace operacje (które zapewne każdy re- chodzić po drzewie).

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

Aktualizacja:

Jak Erik sugeruje w komentarzach, można również napisać logikę local:update-ids w XSLT (używając xdmp:xslt-eval lub xdmp:xslt-invoke wykonać) i powinny być w przybliżeniu równoważne pod względem wydajność. W rzeczywistości, MarkLogic ma naprawdę dobrze napisany wpis w blogu na ten temat:

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

+3

Dla kompletności, trzeci alternatywą jest zastosowanie transformacji XSLT do dokumentu w pamięci. – ehennum

Powiązane problemy