Xquery 多文件上传
Xquery Multiple file upload
我的单个文件上传是这样的:
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 循环的东西,或者有没有函数可以分解它们?
提前致谢!
根据文档,xdmp:get-request-field() 函数签名声明它 returns item* - 因此,您可以预期它会返回一系列项目并且可以通过 xdmp:get-request-field()[1]
、xdmp:get-request-field()[2]
等访问..等..
您可能会考虑在 FLWOR 语句中执行此操作,平衡相同的请求字段和请求文件名(也是相同的签名和相同的顺序)
想知道为什么原来可以认为它是标量? xQuery 方便地将一个项目的序列和标量视为同一事物。
对返回匹配序列的一组函数执行循环对于 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 样式(个人喜好,我希望不要看到 let's repeated each line)
您可以通过其他方式执行此操作,例如请参阅 https://www.w3.org/TR/xpath-functions-31/#func-for-each-pair
中 fn:for-each-pair 的参考实现
有关获取文件扩展名的替代方法,请参阅 How to get file extension in Marklogic Server?
我的单个文件上传是这样的:
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 循环的东西,或者有没有函数可以分解它们?
提前致谢!
根据文档,xdmp:get-request-field() 函数签名声明它 returns item* - 因此,您可以预期它会返回一系列项目并且可以通过 xdmp:get-request-field()[1]
、xdmp:get-request-field()[2]
等访问..等..
您可能会考虑在 FLWOR 语句中执行此操作,平衡相同的请求字段和请求文件名(也是相同的签名和相同的顺序)
想知道为什么原来可以认为它是标量? xQuery 方便地将一个项目的序列和标量视为同一事物。
对返回匹配序列的一组函数执行循环对于 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 样式(个人喜好,我希望不要看到 let's repeated each line)
您可以通过其他方式执行此操作,例如请参阅 https://www.w3.org/TR/xpath-functions-31/#func-for-each-pair
中 fn:for-each-pair 的参考实现有关获取文件扩展名的替代方法,请参阅 How to get file extension in Marklogic Server?