我有以下xml文件。我需要找到$ c中不属于$ v的成员:
(C) - (V) = desired result
let $c := /transport/trips/trip
let $v := /transport/trips/trip
where (data($c/@vehicle)="PKR856")
return
<result2>
{$v/(from|to|through)/string()}
{$c/(from|to|through)/string()}
</result2>
现在我想减去它们,这是我的代码:
let $c := /transport/trips/trip
let $v := /transport/trips/trip
where (data($c/@vehicle)="PKR856")
return
<result2>
{ $c/(from|to|through)/string()[not(. = $v/(from|to|through)/string())]}
</result2>
我试过这也不是工作:
let $c := /transport/trips/trip/
let $v := /transport/trips/trip/(from|to|through)/string()
where (data($c/@vehicle)="PKR856")
return
<result2>
{ $c/(from|to|through)/string()[not(. = $v)]}
</result2>
输出:
内部错误代码,参数
修改
这是XML文件:
<trips>
<trip driver="d2345" vehicle="PKR856" date="12-DEC-2007">
<from>London</from>
<to>Newcastle</to>
<through stop="1">Leicester</through>
<through stop="2">Nottingham</through>
<time>1</time>
</trip>
<trip driver="d6767" vehicle="UUQ007" date="10-MAY-2008">
<from>Paris</from>
<to>Rome</to>
<through stop="1">Lyon</through>
<through stop="2">Milan</through>
<time>15</time>
</trip>
<trip driver="d2345" vehicle="PKR856" date="14-DEC-2007">
<from>Paris</from>
<to>Amsterdam</to>
<through stop="2">Brussel</through>
<through stop="1">Mons</through>
<time>4</time>
</trip>
</trips>
我需要返回特定车辆号码未访问的城市名称吗?
我试过这些但是没有用:
let $driver-cities := /trips/trip[@vehicle="PKR856"]/(from, to, through)/string()
return /trips/trip/(from, to)/string()[not(. = $driver-cities)]
我实际上将答案改为:
let $c := /transport/trips/trip/(from|to|through)/text()
let $v := /transport/trips/trip[@vehicle eq "PKR856"]/(from|to|through)/text()
return
<result>
{ $c except $v}
</result>
答案 0 :(得分:0)
您可以使用except
运算符来获得两组的差异。也许以下内容对您有用:
let $c := /transport/trips/trip
let $v := /transport/trips/trip[@vehicle eq "PKR856"]
return
$c except $v
虽然您的其中一个集合是所有trip
元素的完整集合,但以下结果会产生相同的结果,对我来说似乎更简单:
/transport/trips/trip[@vehicle ne "PKR856"]
与@Bernard合作,我相信最简单的理想答案是:
let $x := /transport/trips/trip[@vehicle ne "PKR856"]/(from|to|through)/text()
return
<result>{$x}</result>
答案 1 :(得分:0)
在XQuery 3.0中,您可以使用group by
clause查找已访问过该城市的所有车辆。然后,这可用于过滤特定车辆未访问过的城市的结果:
let $vehicle := 'UUQ007'
for $trip in //trip
let $curr-vehicle := $trip/@vehicle/string()
for $city in $trip/(from, through, to)/string()
group by $city
where not($curr-vehicle = $vehicle)
return $city
这将为您的示例文档返回London Newcastle Leicester Nottingham Amsterdam Brussel Mons
。如果您设置$vehicle := 'PKR856'
,则结果为Rome Lyon Milan
。我在BaseX的最新版本中试过这个。
如果您的处理器不支持XQuery 3.0,则以下查询可能效率较低,但在XQuery 1.0中计算相同的结果:
let $vehicle := 'UUQ007'
for $city in distinct-values(//trip/(from, through, to))
where not(//trip[@vehicle=$vehicle]/(from, through,to) = $city)
return $city