简体   繁体   English

使用XQL / exist-db将文档上传到服务器

[英]Uploading documents to a server using XQL/exist-db

APP Structure APP结构

NiC
| upload.xq
| upload.html
| controller.xql
| assignments.html (a lot of files are in the main dir, which is probably not good)
| templates/page.html
| inReview/
| data/all the xml files currently in the database
| images/all the images currently in the db
| modules/app.xql
| modules/view.xql

Not all the files are here, but just some that are relevant and to give a flavor. 并不是所有的文件都在这里,而是一些相关的文件并带有某种风味。

New discovery and problem as it now stands 当前的新发现和新问题

I have been trying to get this uploader to work, and I've been stymied at every turn--BUT, I think it is finally working. 我一直在努力使这个上传器正常工作,但我动不动就受阻了-但是,我认为它终于可以工作了。 However, it works in a very weird way, and I don't know why. 但是,它的工作方式很怪异,我不知道为什么。 Not knowing why it works this way and not another way is driving me crazy, and it will cause other problems down the line. 不知道为什么以这种方式而不是其他方式使我发疯,这将导致其他问题。 So, I'm hoping someone can shed some light! 所以,我希望有人能有所启发!

I'm basically hacking together something new from pieces of the sample Shakespeare archive in eXist-db. 我基本上是从eXist-db中的示例莎士比亚档案片段中窃取一些新东西。 So, the structure of my whole app is virtually the same as the ship-with demo. 因此,我整个应用程序的结构实际上与附带的演示程序相同。 That having been said: 话虽如此:

in page.html, which templates the whole look of the page and provides the header/navigation information: 在page.html中,该模板将页面的整体外观模板化,并提供标题/导航信息:

I have added a link to the navigation that goes to an upload page: 我已经添加了指向上载页面的导航的链接:

<li><a href="../upload.html">Contribute</a></li>

upload.html: upload.html:

<div xmlns="http://www.w3.org/1999/xhtml" class="templates:surround?with=templates/page.html&amp;at=main">
        <form enctype="multipart/form-data" method="post" action="upload.xql">
            <fieldset>
            <legend>Upload an XML File for Review:</legend>
            <input type="file" name="file"/>
            <button id="f-btn-upload" name="f-btn-upload" value="true" type="submit" class="btn btn-danger">Upload</button>
        </fieldset>
    </form>
</div>

upload.xql: upload.xql:

xquery version "3.0";

let $collection := '/db/apps/NiC/inReview/'
let $filename := request:get-uploaded-file-name('file')

(: make sure you use the right user permissions that has write access to this collection :)
let $login := xmldb:login($collection, 'username', 'superstrongpassword')
let $store := xmldb:store($collection, $filename, request:get-uploaded-file-data('file'))


return
<results>
   <message>File {$filename} has been stored at collection={$collection}.</message>
</results>

All of this works, somehow. 所有这些都以某种方式起作用。 But the weird thing is in the controller.xql: 但是奇怪的是在controller.xql中:

Here's the relevant bit: 这是相关的位:

else if ($exist:resource = ("search.html", "form1.html", "demo-queries.html", "search-help.html", "about-NiC.html", "assignments.html", "success.html", "upload.html")) then
    (: the html page is run through view.xql to expand templates :)
    (: question: 11/2017 why if upload.html is noted here does the URL need to be relative to ../upload.html from page.html, though others don't? :)
    <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <forward url="{$exist:controller}/{$exist:resource}">
            <set-header name="Cache-Control" value="no-cache"/>
        </forward>
        <view>
            <forward url="{$exist:controller}/modules/view.xql"/>
        </view>
        <error-handler>
            <forward url="{$exist:controller}/error-page.html" method="get"/>
            <forward url="{$exist:controller}/modules/view.xql"/>
        </error-handler>
    </dispatch>

If in page.html I use just the link "upload.html" as the controller would seem to require (upload.html is in the same place and doing the same kind of thing in general that the other pages are, like assignments.html and so on) it doesn't work. 如果在page.html中,我仅使用控制器似乎需要的链接“ upload.html”(upload.html与其他页面在同一位置,并且通常在做其他页面一样的事情,例如assignments.html)依此类推)无效。 I get the SAX exception error/content not allowed in prolog. 我收到序言中不允许的SAX异常错误/内容。 The other pages are accessible, and the URL resolution is working as expected. 其他页面可访问,并且URL解析按预期工作。 But if the link is "../upload.html," the page is accessible and the upload works as I want it to. 但是,如果链接为“ ../upload.html”,则可以访问该页面,并且可以按照我的要求进行上传。

So my question is this: why? 所以我的问题是:为什么? Why can't I just use upload.html as the path, trusting the controller to do what it does? 为什么我不能仅仅使用upload.html作为路径来信任控制器来完成它的工作? Why do I have to gerrymander a solution with the relative path? 为什么我必须通过相对路径来解决问题?

Argh! 啊!

The return type of request:get-uploaded-file-data() is xs:base64Binary* while xmldb:store() expects "either a node, an xs:string, a Java file object or an xs:anyURI" (from the function documentation). request:get-uploaded-file-data()的返回类型为xs:base64Binary*xmldb:store()期望“节点,xs:string,Java文件对象或xs:anyURI”(来自功能文档)。 So you have to pipe the result through util:binary-to-string() first like 因此,您必须首先通过util:binary-to-string()结果

xmldb:store($collection, $filename, util:binary-to-string(request:get-uploaded-file-data('file')))

The error you see is because xmldb:store() throws an XPathException if unsuccessful. 您看到的错误是因为xmldb:store()如果不成功,则会抛出XPathException。

So just to clarify your app structure is? 因此,仅是澄清您​​的应用程序结构是什么?

yourapp
| modules/upload.xq
| templates/page.html
| upload.html
| other1.html
| controller.xql

Do your other1.html files also call .xq modules? 您的other1.html文件还会调用.xq模块吗? The controller handles .html and .xq files differently, so to go from modules/upload.xq you need to use a relative path step ../ to reach upload.html. 控制器对.html和.xq文件的处理方式不同,因此要从modules / upload.xq进行操作,您需要使用相对路径步骤../才能到达upload.html。

That being said, you are not alone in often being dumbfunded by the templating system's opinion on where things are at the moment :) 话虽这么说,您并不孤单,常常会因模板系统对当前情况的看法而感到愚蠢:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM