如何减少XQuery结果中的重复节点?

时间:2015-12-16 05:35:15

标签: xquery

目前,我遇到了重复节点的问题。 这是我遇到重复节点结果的查询。

for $cityA in doc("countries.xml")//city
for $cityB in doc("countries.xml")//city
where not ($cityA is $cityB) and $cityA/name = $cityB/name
return $cityA/name

我的查询结果如下:

<name>Hyderabad</name>
<name>Hyderabad</name>

但我想要的是:

<name>Hyderabad</name>

我理解查询中的问题,为什么会出现重复问题。但是:如何在没有重复的情况下获得结果?

countries.xml file is available for download

2 个答案:

答案 0 :(得分:2)

问题在于您计算了交叉产品,然后进行过滤。有不同的方法来缓解这种情况。显而易见的是只返回不同的值:

for $city in distinct-values(
  for $cityA in doc("countries.xml")//city
  for $cityB in doc("countries.xml")//city
  where not ($cityA is $cityB) and $cityA/name = $cityB/name
  return $cityA/name
)
return <name>{ $city }</name>

但这感觉就像一个可怕的黑客。更好地确保您只返回“第一个”结果,这可以使用<<子句中的节点顺序运算符where来完成:

for $cityA in doc("countries.xml")//city
for $cityB in doc("countries.xml")//city
where not ($cityA is $cityB) and $cityA/name = $cityB/name
where $cityA << $cityB
return $cityA/name

但是,这仍然是不必要的显性交叉产品。您无需更改查询即可:

for $city in doc("countries.xml")//city
where $city/following::city[name=$city/name]
return $city/name

这个循环遍历所有城市,并选择具有相同值的文档中稍后发生的另一个城市。您甚至可以使用谓词在一行中使用普通XPath 1.0(作为XQuery的子集)执行相同的查询:

doc("countries.xml")//city[following::city/name=name]/name

答案 1 :(得分:0)

在XQuery 3.0中,您可以使用分组

for $city in doc('countries.xml')//city
group by $name := $city/name
where count($city) ge 2
return <name>{$name}</city>
相关问题