xml - 将全局映射变量与 BaseX 集合一起使用
问题描述
我正在使用 BaseX (v9.3.2) XQuery v3.1。我有一个 XQuery 脚本,用于评估 BaseX 集合中的所有 XML 文件。该集合有大约 100 个文件,每个文件的大小在 30MB 到 1.5GB 之间,并且具有相同的 XSD 架构。性能更好的脚本使用 BaseX Map Module将键映射到值并通过键快速获取值。我已经声明了几个模块全局变量类型map(*)
。关键是键值仅在一个XML 文件中是唯一的。为了使密钥在整个集合中唯一,我只是添加base-uri($value),'_'
了密钥的附加部分:)。它工作正常。我看到的主要缺点是需要通过所有连续的函数调用来隧道化,即使base-uri
FooN($baseuri, $arg2) FooN-1($baseuri, $arg2) ... Foo1($baseuri, $arg2)
$baseuri
value 在第一次调用时设置,FooN($baseuri, $arg2)
但仅在执行链的最后一个函数中使用。为了更清楚,请参阅下面的 XQuery 代码。这里$basuri
最后只需要 inhelper:Foo1
但我们也需要将它作为参数传递helper:Foo2
。
我的问题是,关于参数隧道是否有更好的方法并且没有其他缺点(性能、内存)。
XQuery 代码
xquery version "3.1" encoding "utf-8";
declare namespace helper="helperns";
declare variable $helper:root := db:open("BMW");
declare variable $helper:mapAS_ApplicationRecordElementByTypeRef as map(*) := map:merge(for $value in $helper:root//*:APPLICATION-RECORD-ELEMENT[*:TYPE-TREF/@DEST='APPLICATION-PRIMITIVE-DATA-TYPE'] return map:entry(concat(base-uri($value),'_',$value/*:TYPE-TREF/tokenize(text(),'/')[last()]), $value));
declare variable $helper:mapAS_ImplementationDataTypeRefByApplicationDatatypeRef as map(*) := ...
...
declare function helper:Foo1($applPrimitiveDataType as element(),$basuri as xs:string)
as element() {
let $applRecordElement := map:get($helper:mapAS_ApplicationRecordElementByTypeRef, concat($basuri,'_',$applPrimitiveDataType/*:SHORT-NAME/text()))
...
let $resolved := if($implDataTypeElement) then (
...
)
else (
<RESOLVED_DATATYPE>
<SHORT-NAME resolveinfo='not resolved (DB ERROR)'>unknown</SHORT-NAME>
</RESOLVED_DATATYPE>
)
return ($resolved)
};
...
declare function helper:Foo2($basuri as xs:string)
as element()* {
let $applicationPrimitiveDataTypes := ...
let $res :=
for $applicationPrimitiveDataType in $applicationPrimitiveDataTypes
...
order by $shortname
return (
if (not($implDataTypeRef)) then (
let $dataTypeResolved := helper:Foo1($applicationPrimitiveDataType,$basuri)
return(
<MAPPING appldtname="{$shortname}" size="{$dataTypeResolved/*:SHORT-NAME/@size}" basedatatype="{$dataTypeResolved/*:SHORT-NAME}" resolveinfo="{$dataTypeResolved/SHORT-NAME/@resolveinfo}"/>
)
)
)
return($res)
};
let $mappingsForAllDocs :=
for $doc in helper:getAllDocs()/doc
...
let $missingmappings := helper:Foo2($doc/@baseuri)
return (
<FILE name="{$doc/@filename}" missing="{count($missingmappings)}">
<MISSING-MAPPING>{$missingmappings}</MISSING-MAPPING>
...
</FILE>
)
let $allDocs :=
for $doc in helper:getAllDocs()/doc
order by $doc/@filename
return (
<FILE name="{$doc/@filename}"/>
)
return($mappingsForAllDocs)
解决方案
您是否考虑过使用唯一 ID 更新 XML 文件(或生成新文件集)?一旦有了唯一的 ID,像 BaseX 这样的 XML 数据库就能够使用该fn:id()
函数进行快速查找。如需更新 XML 文件,请参阅https://docs.basex.org/wiki/XQuery_Update。
推荐阅读
- javascript - 如何在 React App 中使用导航栏重新路由到页面然后滚动到元素?
- python - 为什么变量总是设置为列表中的最后一项?
- go - 在完成时处理任意数量的 goroutines 的输出
- reactjs - 使用 nginx 和 react/django 部署应用程序失败
- javascript - 如何计算围绕其中心旋转的矩形的边界框?
- java - 如何在java中组合两个类
- python - Django MultiValueDictKeyError 处理媒体
- python-3.x - 已经在 Pycharm 终端中设置后,我仍然得到: Please set GOOGLE_APPLICATION_CREDENTIALS
- python - 计算特定类别的每行高于或低于平均值的百分比
- javascript - 在发送到后端之前访问“multipart/form-data”图像缓冲区