2013-09-04 35 views
5

Tôi đang cố gắng thay đổi giá trị của một số nút trong một tệp XML rất lớn được tải trong bộ nhớ từ một biểu mẫu web.Thay đổi giá trị XML trong bộ nhớ bằng xQuery

Các tập tin thu được như thế này:

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

Vì vậy, như bạn sẽ nhìn thấy tập tin là trong bộ nhớ.

Bây giờ, tôi cần phải thay đổi giá trị của hàng ngàn nút, và cho đến nay tôi đã không thể làm điều đó một cách tối ưu.

Bất kỳ ý tưởng nào?

Một số trong những điều tôi đã tryied cho đến nay:

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 
     (

     ) 

Thư viện mem là một phong tục tải một.

Trả lời

4

Nếu có thể, hãy chèn tài liệu vào cơ sở dữ liệu và cập nhật giao dịch riêng biệt các nút bằng cách sử dụng 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) }); 

Ngoài ra, nếu bạn phải cập nhật các tài liệu trong bộ nhớ, nó có lẽ là tối ưu hơn đi bộ trên cây chỉ một lần (cho việc cập nhật của bạn tất cả các hoạt động đó), chứ không phải là nhiều mem:replace hoạt động (mà có lẽ mỗi lại đi bộ cây).

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

Cập nhật:

Như Erik gợi ý trong các ý kiến, bạn cũng có thể viết logic của local:update-ids trong XSLT (sử dụng xdmp:xslt-eval hoặc xdmp:xslt-invoke để thực hiện), và họ nên được tương đương về mặt hiệu suất. Trong thực tế, MarkLogic có một blog entry rất tốt bằng văn bản về đề tài này:

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

+3

Để hoàn chỉnh, một lựa chọn thứ ba là để áp dụng một XSLT chuyển đổi các tài liệu trong bộ nhớ. – ehennum