Xquery多个文件上传

时间:2018-01-29 15:07:00

标签: html xquery marklogic

我的单个文件上传如下:

declare function local:uploadFile()
{

let $file := xdmp:get-request-field("upload")
let $filename := xdmp:get-request-field-filename("upload")
let $contenttype := xdmp:get-request-field-content-type("upload")
let $extension := fn:replace($filename, '.*\.', '')
let $insert := switch ($contenttype)
    case "text/xml"
    case "text/xhtml"
    case "text/csv"
    case "text/plain"
    case "application/json"
        return xdmp:document-insert($filename,xdmp:unquote($file))
    case "application/octet-stream"
        return switch ($extension)
        case "gpx"
            return xdmp:document-insert($filename,xdmp:unquote(xdmp:quote(binary{xs:hexBinary($file)})))
        default
            return xdmp:document-insert($filename,$file)
    default
        return xdmp:document-insert($filename,$file)
return fn:concat("file '",$filename,"' uploaded, contenttype: ",$contenttype," extension: ",$extension)
};

现在我想更改它以支持多个文件。 它使用的html表单支持通过添加multiple="true"属性上传多个文件。

它看起来像这样:

<form name="test" action="upload.xqy" method="post" enctype="multipart/form-data">
    <p><label>File to upload:
    <input type="file" class="name" name="upload" size="50" multiple="true" /></label></p>
    <p><input type="submit" value="Upload and Get Results"/></p>
    </form>

问题是如果我尝试上传多个文件,get-request-field()语句会返回多个参数。我尝试使用fn:tokenize(),但这不起作用。有没有像我可以使用的for-loop那样的东西,还是有功能来分解它们?

提前谢谢!

2 个答案:

答案 0 :(得分:3)

对于xquery新手来说,在返回匹配序列的一组函数中执行循环可能会很棘手。有很多方法可以做到这一点。这是一个简单的:

  for $file at $pos in xdmp:get-request-field("upload")
    let $filename := xdmp:get-request-field-filename("upload")[$pos],
      $contenttype := xdmp:get-request-field-content-type("upload")[$pos],
      $extension := fn:replace($filename, '.*\.', ''),
      $insert := switch ($contenttype)
   ... 

注意使用$ pos仅从第一个序列中提取位置,然后使用它从每个其他请求中提取正确的项目。

注意:使用替代的let风格(个人喜好,我更喜欢看不到让我们重复每一行)

您可以通过其他方式执行此操作,例如,请参阅https://www.w3.org/TR/xpath-functions-31/#func-for-each-pair中的fn:for-each-pair的参考实现

有关获取文件扩展名的替代方法,请参阅How to get file extension in Marklogic Server?

答案 1 :(得分:2)

根据文档,xdmp:get-request-field()函数签名声明它返回item * - 因此,您可以期望它返回一系列项目,并且可以通过xdmp:get-request-field()[1]访问, xdmp:get-request-field()[2]等等..等等。

可能你会考虑在FLWOR语句中使用request-filename平衡相同的请求字段(也是相同的签名和相同的顺序)

想知道为什么你最初可以认为它是一个标量? xQuery方便地将一个项目和一个标量的序列视为同一个事物。