将主数据与 XML 中存在的元素进行比较

Compare Master data with elements present in the XML

<MasterData>
  <Name>AA</Name>
  <EmpId>123</EmpId>
  <AccountNo>111</AccountNo>
   <IFSC>ABC</IFSC>
  <AccountData>
    <AccountNo>111</AccountNo>
    <IFSC>ABC</IFSC>
  </AccountData>
  <AccountData>
    <AccountNo>222</AccountNo>
    <IFSC>DEF</IFSC>
  </AccountData>
</MasterData>

我的数据库中有一个这样的 xml,我需要检查 MasterData 中存在的 AccountNo+IFSC 组合(不在 AccountData 部分下)并与收集并检查它是否与 AccountData 部分中存在的数据匹配,如果匹配则标识文档的 URI。 首先从 Masterdata 部分识别 AccountNo+IFSC 的唯一组合,然后检查此组合是否存在于任何 AccountData 部分下,此 xml 除了 AccountNo 和 IFSC

之外还有更多元素

如果您在 AccountNoIFSC 元素上有范围索引,那么您可以:

  1. AccountNoIFSC 和带有 cts:value-tuples()cts:uri-reference() 检索值集。
  2. 使用具有 AccountNoIFSC 值的复合键创建地图,并将 URI 作为这些地图条目的值
  3. 删除任何只有一个 URI 关联的条目
  4. return 将具有对应于 AccountNoIFSC
  5. 的每个组合的一组 URI 的映射

像这样:

let $accountNumber-IFSC := 
  cts:value-tuples(
    (
      cts:element-reference(xs:QName("AccountNo")), 
      cts:element-reference(xs:QName("IFSC")),
      cts:uri-reference()
    )
   )
let $map := map:new()
let $_create_map_value_to_uris := for $co-occurrence in $accountNumber-IFSC
let $key := concat($co-occurrence[1], " ", $co-occurrence[2])
let $value := (map:get($map, $key), $co-occurrence[3])
return map:put($map, $key, $value)

let $_prune_single_uri :=  
  for $key in map:keys($map)
  let $value := map:get($map, $key)
  where not(tail($value))
  return 
    map:put($map, $key, ())
  
return 
  $map

如果你只想要 URI 列表,你可以反转映射:-$map 和 return 它是键:return map:keys(-$map)

如果您在 EmpId 上有一个范围索引,您可以以此为中心而不是文档 URI。

使用 Optic API functions,您可以对元素范围索引执行类似的操作:

import module namespace op = "http://marklogic.com/optic" at "/MarkLogic/optic.xqy";

op:from-lexicons(
  map:entry("AccountNo", cts:element-reference(xs:QName("AccountNo"))) 
  => map:with("IFSC", cts:element-reference(xs:QName("IFSC")))
  => map:with("URI", cts:uri-reference())
)
=> op:group-by(
    ("IFSC", "AccountNo"), 
    (
      op:group-concat("URIs", "URI", map:entry("separator", ", ")), 
      op:count("count", op:col("URI"))
    )
  )
=> op:where(op:gt(op:col("count"), 1))
=> op:result()