如何避免 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)
这是新手问题。我最近才开始学习 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)