1

In eXist-db 4.4, XQuery 3.1, I am using automation to compress a number of xml files. The problem is that when they compress they are storing only the text content and not the xml content.

This function uses compression:zip to create a zip from a batch of documents:

declare option exist:serialize "expand-xincludes=no";
declare option exist:serialize "method=xml media-type=application/xml";
declare function zip:create-zip-by-batch()
{
    [...]

    let $zipobject := compression:zip(zip:get-entry-for-zip($x,false())

    let $zipname := "foozipname.zip"

    let $store := xmldb:store("/db/foodirectory", $zipname, $zipobject)

    return $store
};

The above calls this function, where the documents are serialized and put into <entry> per documentation:

declare option exist:serialize "expand-xincludes=no";
declare option exist:serialize "method=xml media-type=application/xml";
declare function zip:get-entry-for-zip($x) 
{

 [...for each $foo document in $x, create an <entry>...]

 let $serialized := serialize($foo, map { "method": "xml" })
 let $entry =
          <entry name="somefooname" type='xml' method='store'>
               {$serialized}
          </entry>

 [...return a sequence of $entry...]
 }

I think it's missing a configuration for serialization, but I can't figure it out...

Thanks in advance for any help.

jbrehr
  • 775
  • 6
  • 19

1 Answers1

3

Here a query for eXist demonstrating how to compress XML documents into a ZIP file and store it into one's database:

xquery version "3.1";

(: create a test collection with 10 test files: 1.xml = <x>1</x> 
   thru 10.xml = <x>10</x> :)
let $prepare := xmldb:create-collection("/db", "test")
let $populate := (1 to 10) ! xmldb:store("/db/test", . || ".xml", <x>{.}</x>)

(: construct zip-bound <entry> elements for the documents in the test collection :)
let $entries := collection("/db/test") ! 
    <entry name="{util:document-name(.)}" type="xml" method="store">{
        serialize(., map { "method": "xml" })
    }</entry>

(: compress the entries and store in database :)
let $zip := compression:zip($entries, false())
return
    xmldb:store("/db", "test.zip", $zip)

The resulting ZIP file contains the 10 test XML documents, intact. For a variant showing how to write the ZIP file to a location on your file system, see https://gist.github.com/joewiz/aa8d84500b1f1478779cdf2cc1934348.

For a fuller discussion of serialization options in eXist, see my answer to an earlier question: https://stackoverflow.com/a/49290616/659732.

Joe Wicentowski
  • 5,159
  • 16
  • 26
  • When I look at this it seems identical to what I posted. – jbrehr Jan 15 '19 at 10:02
  • In preparing it I boiled the code down to the essential steps to see if I could reproduce your result, but it actually worked. If you can modify it to reproduce your original result, we could see if it qualifies as a bug. But did the code here work for you? – Joe Wicentowski Jan 15 '19 at 14:44
  • 1
    I rebuilt it step by step using your model and it works - somehow I was not handling the serializer correctly. Nonetheless that issue is fixed, thank you! However, I have run into a subsequent problem of stopping output of `xincludes` which I have posted here: https://stackoverflow.com/questions/54215193/exist-db-serialize-expand-xincludes-no-not-working . Also, my site has gone live in beta version, and it includes a thank you to you and a few others on SO for the valuable assistance you've given me http://medieval-inquisition.huma-num.fr/editorial/acknowledgements – jbrehr Jan 16 '19 at 10:39
  • Good to hear this works. Your acknowledgement of the SO folks who've helped you is very kind. Congratulations on the launch - what an amazing resource you've built/are building! Please consider announcing the release of the resource on the [exist-open mailing list](https://sourceforge.net/p/exist/mailman/), if not also TEI-L. There will be great interest, I'm sure – Joe Wicentowski Jan 16 '19 at 15:14