我有很多XML文件,我需要根据命令行中用户定义的输入输出文件名。
这是一个简单的XQuery示例,它捕获了问题的本质。
File1.xml
<?xml version="1.0" encoding="utf-8"?>
<Description>
<FileName>File1</FileName>
<Persons>
<Person>
<Name>Anna</Name>
<Age>25</Age>
</Person>
<Person>
<Name>Marco</Name>
<Age>25</Age>
</Person>
<Person>
<Name>Mary</Name>
<Age>13</Age>
</Person>
</Persons>
</Description>
File2.xml
<?xml version="1.0" encoding="utf-8"?>
<Description>
<FileName>File2</FileName>
<Persons>
<Person>
<Name>Anna</Name>
<Age>25</Age>
</Person>
<Person>
<Name>Marco</Name>
<Age>11</Age>
</Person>
</Persons>
</Description>
例如,用户需要获取包含人员的文件的名称:25岁的Anna和25岁的Marco。 我写了一个脏的解决方案。 我想知道是否可以通用形式为任意数量的输入对(名称,年龄)。
此处,输入在search.xq中进行了硬编码。
search.xq
(: person and age are user defined inputs of arbitrary length :)
let $person:= ('Anna', 'Marco')
let $age:= (25, 25)
(: Output needs to be name of file which have person (Anna, 25) and (Marco,25):)
return collection('db')/Description/Persons/Person[(Name=$person[1] and Age=$age[1])]/../Person[(Name=$person[2] and Age=$age[2])]/../../FileName
输出:
<FileName>File1</FileName>
提前致谢。
答案 0 :(得分:2)
这是一个可能的解决方案(假设您的XQuery处理器允许您将地图作为用户定义的输入传递):
declare variable external $INPUT := map {
'Anna': 25,
'Marco': 25
};
for $description in collection('db')/Description
where every $test in map:for-each($INPUT, function($name, $age) {
exists($description/Persons/Person[Name = $name and Age = $age])
}) satisfies $test
return $description/FileName
第二种选择更接近原始解决方案。名称和年龄必须分开变量:
declare variable $NAMES external := ('Anna', 'Marco');
declare variable $AGES external := (25, 25);
for $description in collection('db')/Description
where every $test in for-each-pair($NAMES, $AGES, function($name, $age) {
exists($description/Persons/Person[Name = $name and Age = $age])
}) satisfies $test
return $description/FileName