我是xquery的新手,有一个问题无法解决。
我想迭代一个xml并在映射中保存一些条目。这样我就可以合并具有不同值的相同键(StringValue1、StringValue2(。最后,我想返回完整的地图并将其保存到一个文件中。跟随你找到我的代码。我使用xbase来执行这些xquerys。
代码
declare namespace functx = "http://www.functx.com";
(: Function should merge the values, if the map contains the key, else it should put the new entrie to the map.:)
declare function functx:pnMap($map as map(*), $key as xs:anyAtomicType, $value as item()*) as map(*) {
if(map:contains($map, $key)) then (map:merge(($map, map{$key:$value}), map{"duplicates":"combine"})) else map:merge((map{ $key: $value }, $map))
} ;
let $pnMap := map{}
for $x in doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity
return functx:pnMap($pnMap, substring-before((substring-after(data($x/BigUnsortedStringField), 'Owner: ')), '
'), string-join(('Position=Owner | ', 'EntityID=', data($x/@id),' | ', 'SomeOtherNo=', data($x/IDNumberTypes/ID[@IDType="StringWhereIfindsomeOtherNumber"])), ''))
结果
map {
"Nick": "Position=Owner | EntityID=625115 | SomeOtherNo=7206512"
}
map {
"James": "Position=Owner | EntityID=1016624 | SomeOtherNo=9138056"
}
map {
"Nick": "Position=Owner | EntityID=1016625 | SomeOtherNo=9051648"
}
map {
"Pete": "Position=Owner | EntityID=1016626 | SomeOtherNo=9051636"
}
map {
"Jon": "Position=Owner | EntityID=1016675 | SomeOtherNo=9349667"
}
预期结果1
map {
"Nick": "Position=Owner | EntityID=625115 | SomeOtherNo=7206512, Position=Owner | EntityID=1016625 | SomeOtherNo=9051648"
"James": "Position=Owner | EntityID=1016624 | SomeOtherNo=9138056"
"Pete": "Position=Owner | EntityID=1016626 | SomeOtherNo=9051636"
"Jon": "Position=Owner | EntityID=1016675 | SomeOtherNo=9349667"
}
这是XML的缩写摘录:
<Entity id="1016626">
<Status>Active</Status>
<IDNumberTypes>
<ID IDType="SomeOtherNo">
<IDValue>9051636</IDValue>
</ID>
</IDNumberTypes>
<BigUnsortedStringField>Some text
Owner: Pete
Sister: Magrit
Next Line text
more text
</BigUnsortedStringField>
</Entity>
<Entity>
....
</Entity>
我想你想要
map:merge(
doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity !
map:entry(
substring-before(substring-after(BigUnsortedStringField, 'Owner: '), ' '),
string-join(('Position=Owner', 'EntityID=' || @id, 'SomeOtherNo=' || IDNumberTypes/ID[@IDType="StringWhereIfindsomeOtherNumber"]), ' | ')
),
map { 'duplicates' : 'combine' }
)
但是编写代码时很难不看到XML输入。
作为一种替代方案,您也可以尝试使用XQuery组,方法是首先对所需的数据进行分组,然后创建分组结果的映射:
map:merge(
for $entity in doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity
group by $owner := substring-before(substring-after($entity/BigUnsortedStringField, 'Owner: '), ' ')
return
map:entry($owner, string-join(
$entity!string-join(('Position=Owner', 'EntityID=' || @id, 'SomeOtherNo=' || IDNumberTypes/ID[@IDType="StringWhereIfindsomeOtherNumber"]), ' | '), ' , '))
)