0

In eXist 4.4/XQuery 3.1, I am building a function to compress a number of xml files into a zip using compression:zip.

I have one function which collects all the URIs for the documents to be compressed, schedule:get-document-uris-for-zip(xmlid as xs:string). This function returns lists of documents like the following:

/db/apps/deheresi/data/MS609-0001.xml
/db/apps/deheresi/data/MS609-0002.xml
/db/apps/deheresi/data/MS609-0003.xml
/db/apps/deheresi/data/MS609-0004.xml
/db/apps/deheresi/data/MS609-0005.xml
/db/apps/deheresi/data/MS609-0006.xml
/db/apps/deheresi/data/MS609-0007.xml
/db/apps/deheresi/data/MS609-0008.xml
/db/apps/deheresi/data/MS609-0009.xml
/db/apps/deheresi/data/MS609-0010.xml

This function is called by the compression function as follows

declare function schedule:create-zip-by-batch()
{
  let $batch := doc(concat($globalvar:URIdocuments,"document_collections.xml"))

  for $entry in $batch//collection[@compile="y"]

    let $zipobject := compression:zip(schedule:get-document-uris-for-zip($entry/string(@xml:id)),false())

    let $zipstore := xmldb:store("/db/apps/deheresi/documents",
                                 "MS609_tei.zip", 
                                 $zipobject)

    return $zipstore
};

This is throwing a cast error as follows, but I can't identify how to resolve this...

org.exist.xquery.value.StringValue cannot be cast to org.exist.xquery.value.AnyURIValue

Many thanks in advance.

Edit - I'm adding here the part of the function schedule:get-document-uris-for-zip(xmlid as xs:string) which outputs the list of URIs. The URIs are built through string concatenation:

       (: get names of documents which meet criteria :)
       let $list := xmldb:get-child-resources("/db/apps/deheresi/data")[starts-with(., $y/string(@filename)) and ends-with(., $y/string(@ext))]

        (: create URI for each document :)   
        return 
             for $n in $list
             return concat("/db/apps/deheresi/data/",$n)
jbrehr
  • 775
  • 6
  • 19

1 Answers1

1

You're right to find this function a bit confusing. The (eXist-specific) compression:zip() function $sources parameter is typed as if it is quite flexible way, as xs:anyType()+. But really it is quite strict about the two types of item it accepts: a sequence of URIs (i.e., of type xs:anyURI), or a sequence of <entry> elements:

<entry name="filename.ext" 
       type="collection|uri|binary|xml|text" 
       method="deflate|store"
    >data</entry>

See https://exist-db.org/exist/apps/fundocs/view.html?uri=http://exist-db.org/xquery/compression#zip.2.

The problem with your code is that you are passing strings in your $sources parameter, and have not cast these strings as xs:anyURI.

Here is sample working code:

xquery version "3.1";

let $prepare := 
    (
        xmldb:create-collection("/db", "test"),
        xmldb:store("/db/test", "test.xml", <test/>)
    )
let $zip := compression:zip("/db/test/test.xml" cast as xs:anyURI, false())
return 
    xmldb:store("/db/test", "test.zip", $zip)
Joe Wicentowski
  • 5,159
  • 16
  • 26
  • The same documentation says "$sources The sequence of URI's and/or Entrys" I am trying to pass a sequence of URIs instead of having to construct a list of entries. – jbrehr Nov 12 '18 at 14:07
  • Also, the error reported seems to point to `compression:zip()` accepting URIs, but not able to accept the `xs:string` paths as URIs. – jbrehr Nov 12 '18 at 14:37
  • I managed to trick the function into accepting URIs but the processing took far too long. I switched the process over to `entry` and it works fine. – jbrehr Nov 12 '18 at 18:33
  • 1
    I'd forgotten about the "sequence of URIs" option and overlooked them in my initial answer. I've always used the `` approach because I often zip up in-memory items rather than on-disk resources, and when creating epubs, one of the required metadata resources has to be zipped without compression - using `method="store"`. These options aren't possible with the "sequence of URIs", but I can see how nice it is to avoid constructing `` elements. – Joe Wicentowski Nov 12 '18 at 23:46