我正在使用BaseX (v9.3.2) XQuery v3.1。 我有一个XQuery脚本来评估BaseX集合中的所有XML文件。这个集合有大约100个文件,每个文件的大小在30MB到1.5GB之间,并且具有相同的XSD模式。为了获得更好的性能,该脚本使用了BaseX 地图模块 用于将键映射到值,并通过键快速获取值。我已经声明了几个全局变量,类型为 map(*)
. 症结在于,键值只有在 一个 XML文件。为了使键在整个集合中是唯一的,我已经简单地添加了 base-uri($value),'_'
作为键的附加部分:)。它工作得很好。我看到的主要缺点是需要有 隧道 的 base-uri
通过所有连续的函数调用 FooN($baseuri, $arg2) FooN-1($baseuri, $arg2) ... Foo1($baseuri, $arg2)
纵使 $baseuri
的值是通过第一次调用 FooN($baseuri, $arg2)
但只在执行链的最后一个函数中使用。为了让它更清楚,请看下面的XQuery代码。这里的 $basuri
最后,只有在 helper:Foo1
但我们需要将它作为一个参数传递给 helper:Foo2
也是。
我的问题是,是否有一个更好的方法,在参数隧道方面,没有其他缺点(性能,内存)。
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.orgwikiXQuery_Update。.