-
-
Save peterstadler/fd6ed3b082f0bc602597191fc9153e17 to your computer and use it in GitHub Desktop.
xquery version "1.0"; | |
declare function local:upload() { | |
let $filename := request:get-uploaded-file-name('file') | |
return | |
<results> | |
<message>File {$filename} has been stored.</message> | |
</results> | |
}; | |
local:upload() |
Hmmm. I am getting the same exact problem:
MacBook-Pro-7:Shared tonya-mariehowe$ curl -F "file=/testfile.xml" http://localhost:8080/exist/apps/test/test.xql
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 400 SAX exception while parsing request: Content is not allowed in prolog.</title>
</head>
<body><h2>HTTP ERROR 400</h2>
<p>Problem accessing /exist/apps/test/test.xql. Reason:
<pre> SAX exception while parsing request: Content is not allowed in prolog.</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.3.9.v20160517</a><hr/>
</body>
</html>
MacBook-Pro-7:Shared tonya-mariehowe$
Also: cool to see how that works!!
Oh, no! I see one problem--my path is not right. I corrected that in the curl command and it worked!! Let me see if I can figure it out now. I'll report back!
Okay, so this test case works, but nothing is uploaded. Looking at it, it seems like it's not meant to be uploaded, just to see whether there's a problem at this point or that--right? I tweaked the URL of the local install to ensure that the path was correct, and I got an error message that seemed promising:
err:XPTY0004 checking function parameter 3 in call xmldb:store(untyped-value-check[xs:string, $collection], untyped-value-check[xs:string, $filename], request:get-uploaded-file-data("file")): XPTY0004: The actual cardinality for parameter 3 does not match the cardinality declared in the function's signature: xmldb:store($collection-uri as xs:string, $resource-name as xs:string?, $contents as item()) xs:string?. Expected cardinality: exactly one, got 0. [at line 406, column 51, source: /db/apps/NiC/modules/app.xql]
This seems to suggest that there was no filename to be passed. BUT, when I returned to the upload page and re-submitted the test file, I get the same old problem message--with the right path, this time:
Problem accessing /exist/apps/NiC/form1.html. Reason: SAX exception while parsing request: Content is not allowed in prolog.
So I'm back to square one. Though there might still be a path problem somewhere.
Ah, I think now I see: You are piping request:get-uploaded-file-data("file")
directly to xmldb:store()
but the return type of the former is as xs:base64Binary*
and the latter expects it to be a "either a node, an xs:string, a Java file object or an xs:anyURI" (from the function documentation).
So you have to pipe the result through util:binary-to-string()
first!
Something like this?
declare function app:upload($node as node(), $model as map(*)) {
let $collection := 'db/apps/NiC/inReview'
let $filename := request:get-uploaded-file-name('file')
let $file := util:binary-to-string($filename)
(: make sure you use the right user permissions that has write access to this collection :)
let $login := xmldb:login($collection, 'username', 'superhardpassword')
let $store as xs:string? := xmldb:store($collection, $filename, request:get-uploaded-file-data($file), 'application/octet-stream')
(:let $store := xmldb:store($collection, $filename, request:get-uploaded-file-data('file')):)
I'm sure the syntax is incorrect--I figured I'd try to break something, but I am still receiving the "problem accessing form1.html" SAX exception. So I'm not sure the app:upload is even being run. I'll continue to play with it!
(untested)
declare function app:upload($node as node(), $model as map(*)) {
let $collection := 'db/apps/NiC/inReview'
let $filename := request:get-uploaded-file-name('file')
let $file := util:binary-to-string(request:get-uploaded-file-data('file'))
(: make sure you use the right user permissions that has write access to this collection :)
let $login := xmldb:login($collection, 'username', 'superhardpassword')
let $store as xs:string? := xmldb:store($collection, $filename, $file)
(:let $store := xmldb:store($collection, $filename, request:get-uploaded-file-data('file')):)
Okay, so I got it to work--but in a very strange way. Do you have any insight? I think it's a controller/path issue, but why it works now and doesn't if I trust the controller to do what it's supposed to do is frustrating to no end: https://stackoverflow.com/questions/47182646/uploading-documents-to-a-server-using-xql-exist-db
test.xql
in e.g./db/apps/test/test.xql
curl -F "file=@/path/to/file" http://localhost:8080/exist/apps/test/test.xql