Reputation: 118
Is there a simple way using the Zorba XQuery Processor to update multiple XML files and save the output of the modification back in the same file?
So far I have figured out how to process multiple files using the File module and the file:list extension to find all the XML files in a directory. I then loop through each document and run an XQuery Update statement (replace value of node {} with {}). The problem is that this doesn't actually modify the file.
I was using Saxon before, but the license costs are too expensive for this particular project. In Saxon EE, if I ran a "replace value of node" on an open document, the document would be updated on the disk when the query was finished. I suspect Zorba doesn't work this way, instead only modifying the value in memory during the query. If I was editing one file I would just output the modified XML in Zorba and pipe that back to the input file, but in this case I want to update many files. Is that possible in one query?
Here is what the code looks like:
import module namespace file = "http://expath.org/ns/file";
for $file in file:list("XML", true(), "*.xml")
let $doc := doc(concat("XML/", $file))
return
{
for $key in $doc//key
return
replace value of node $key/texture
with replace($key/material/text(), ".mat", ".png")
}
Upvotes: 1
Views: 978
Reputation: 118
Figured it out! I had to use the XQuery scripting extension that Zorba provides to re-write the result back to the file:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
import module namespace file = "http://expath.org/ns/file";
for $file in file:list("XML", true(), "*.xml")
return
{
variable $doc := doc(concat("XML/", $file));
for $key in $doc//key
return
replace value of node $key/texture
with replace($key/material/text(), ".mat", ".png");
file:write(concat("XML/", $file), $doc,
<output:serialization-parameters>
<output:indent value="yes"/>
<output:method value="xml"/>
<output:omit-xml-declaration value="no"/>
</output:serialization-parameters>
);
}
Upvotes: 2