2013-09-04 3 views
5

웹 양식에서 메모리에로드 된 매우 큰 XML 파일에서 여러 노드의 값을 변경하려고합니다.xQuery를 사용하여 메모리의 XML 값을 변경하십시오.

파일은 다음과 같이 얻을 수있다 :

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

그래서, 당신은 파일이 메모리에 볼 수 있습니다.

이제 수천 개의 노드 값을 변경해야하며 지금까지 최적의 방법으로이를 수행 할 수 없었습니다.

아이디어가 있으십니까?

지금까지 tryied 한 것들 중 일부

:

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 
     (

     ) 

마이크로 전자 기계 라이브러리는 사용자가 하나를 다운로드합니다.

답변

4

가능하면 문서를 데이터베이스에 삽입하고 별도의 트랜잭션으로 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) }); 

또한, 그것은는 아마 각 재 (한 번만 트리를 걸어보다는 여러 mem:replace 작업 (당신의 업데이트 해당 작업의 모든 제작) 아마 더 최적 나무를 걷는다).

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

업데이트 : 에릭이 코멘트에서 알 수 있듯이

, 당신은 또한 (실행 xdmp:xslt-eval 또는 xdmp:xslt-invoke를 사용하여) XSLT에서 local:update-ids의 논리를 쓸 수 있으며,이면에서 거의 동일해야 공연. 완성도를 들어

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

+3

가, 세 번째 대안은 XSLT 메모리에 문서 변환을 적용하는 것입니다 : 사실, MarkLogic 주제에 정말 잘 쓰여진 블로그 항목이 있습니다. – ehennum

관련 문제