如何避免 XQuery 结果中的重复项?

How to avoid duplicates in XQuery results?

这是新手问题。我最近才开始学习 XQuery 和 XPath。

考虑这个XML

<employees>
  <employee empid="1">
    <ename>KING</ename>
    <mgr/>
    <hiredate>17-11-1981</hiredate>
  </employee>
  <employee empid="2">
    <ename>BLAKE</ename>
    <mgr>7839</mgr>
    <hiredate>1-5-1981</hiredate>
    <test>
      <sub1>one</sub1>
      <sub2>two</sub2>
    </test>
  </employee>
</employees>

当我执行以下 XQuery 时,

let $db := db:open("example")
for $item1 in $db/employees/employee,
    $item2 in $db/employees/employee/test
return ($item1/mgr,$item1/ename,$item2/sub1)

我得到了...

<mgr/>
<ename>KING</ename>
<sub1>one</sub1>
<mgr>7839</mgr>
<ename>BLAKE</ename>
<sub1>one</sub1>

我希望得到的结果是...

<mgr/>
<ename>KING</ename>
<mgr>7839</mgr>
<ename>BLAKE</ename>
<sub1>one</sub1>

这是因为sub1只存在于/employee/@empid='2'。

有人能给我指出正确的方向吗?谢谢

这是一种方法。返回前,用if语句检查test/sub1是否存在。

我也稍微更改了 for 子句,删除了 db:open() 函数,但很容易将其重新添加。

for $employee in /employees/employee
return
if ($employee/test/sub1)
then
($employee/mgr, $employee/ename, $employee/test/sub1)
else
($employee/mgr, $employee/ename)

结果将是

<mgr/>
<ename>KING</ename>
<mgr>7839</mgr>
<ename>BLAKE</ename>
<sub1>one</sub1>

You said there is more than one ways to do this, can you please describe further

一种略有不同的方法是使用 if/then/else XPath 表达式并无条件返回此表达式:

for $employee in /employees/employee
return
($employee/mgr, $employee/ename, if ($employee/test/sub1) then $employee/test/sub1 else '')

CiaPan 的回答显示了另一种方式,这次是通过嵌套 for 子句。在我看来,它有点不那么直截了当,但它仍然有效。 CiaPan 还展示了单个 XPath 表达式如何潜在地解决问题 - 这非常简单!

在你的for表达式中

for $item1 in $db/employees/employee,
    $item2 in $db/employees/employee/test

$item1遍历所有employees/employee元素,$item2遍历所有employees/employee/test元素,independent $item1 的当前值是多少。

要获得您需要的东西,您可以试试这个:

for $item1 in $db/employees/employee,
return ($item1/mgr,$item1/ename,
    for $item2 in $item1/test
    return $item2/sub1)

或者,更短的:

$db/employees/employee/(mgr, ename, test/sub1)