我有两个系列。
我需要根据文件名在两个集合之间获得差异。
示例场景:
Collection 1:
/data/1.xml
/data/2.xml
/data/3.xml
collection 2:
/test/1.xml
/test/2.xml
/test/3.xml
/test/4.xml
/test/5.xml
output:
/data/1.xml
/data/2.xml
/data/3.xml
/test/4.xml
/test/5.xml
答案 0 :(得分:4)
使用set delta作为David建议是正确的,但您需要首先为URI生成文件名密钥。地图对此非常有帮助,这使得保持与其原始URI相关联的文件名密钥变得容易。
首先使用文件名密钥和URI值生成两个映射。然后,在地图键上使用set delta,生成一系列diff文件名。然后从源地图中获取这些文件名的URI:
let $x := (
"/data/1.xml",
"/data/2.xml",
"/data/3.xml")
let $y := (
"/test/1.xml",
"/test/2.xml",
"/test/3.xml",
"/test/4.xml",
"/test/5.xml")
let $map-x := map:new($x ! map:entry(tokenize(., '/')[last()], .))
let $map-y := map:new($y ! map:entry(tokenize(., '/')[last()], .))
let $keys-diff-y := map:keys($map-y)[not(. = map:keys($map-x))]
let $diff-y := map:get($map-y, $keys-diff-y)
return ($x, $diff-y)
答案 1 :(得分:3)
两种替代解决方案:
首先,使用一致的键(最后一个斜线后面的子串)将每个项目放在地图中,然后在地图中为每个键选择第一个项目:
let $x := (
"/data/1.xml",
"/data/2.xml",
"/data/3.xml")
let $y := (
"/test/1.xml",
"/test/2.xml",
"/test/3.xml",
"/test/4.xml",
"/test/5.xml")
let $intersection := map:map()
let $_ := ($x, $y) ! (
let $key := tokenize(., "/")[last()]
return
map:put($intersection, $key, (map:get($intersection, $key), .))
)
return
for $key in map:keys($intersection)
for $uri in map:get($intersection, $key)[1]
order by number(replace($uri, ".*/(\d+).xml", '$1'))
return $uri
第二种方法,确保仅为给定密钥设置第一项:
let $x := (
"/data/1.xml",
"/data/2.xml",
"/data/3.xml")
let $y := (
"/test/1.xml",
"/test/2.xml",
"/test/3.xml",
"/test/4.xml",
"/test/5.xml")
let $intersection := map:map()
let $_ := ($x, $y) ! (
let $key := tokenize(., "/")[last()]
return
if (fn:exists(map:get($intersection, $key))) then ()
else map:put($intersection, $key, .)
)
return
for $uri in map:get($intersection, map:keys($intersection))
order by number(replace($uri, ".*/(\d+).xml", '$1'))
return $uri
order by
是可选的,但是对于地图,您可能没有一致的密钥排序。根据需要自定义(例如/ data / uris,然后/ test / uris等),如果不关心URI的顺序,则删除。
答案 2 :(得分:1)
设置符号:
达美:(收益'a')let $c1 := ('a', 'b', 'c')
let $c2 := ('b', 'c', 'd')
return $c1[fn:not(.= $c2)]
交点:(收益率b,c)
let $c1 := ('a', 'b', 'c')
let $c2 := ('b', 'c', 'd')
return $c1[.= $c2]
反转c1和c2以进行其他两种排列。
如需好好阅读,请查看Dave Cassel的post