我在oracle XML表中有以下xml文件。我非常了解XQuery和XML表。我想知道找到所有未被特定车辆访问的城市(登记号码)的可能解决方案是什么。
我想首先我需要一个“for循环”来保存所有城市的名称然后另一个“for循环”我必须检查该城市是否被车辆访问过。有没有办法从所有城市的列表中减去特定车辆访问过的城市的名称。
(所有城市的名称) - (车辆访问的城市)=(城市没有 车辆参观)
这是我的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>
我试过
这是所有城市的列表:
for $form in /transport/trips/trip/from
for $to in /transport/trips/trip/to
return
<result>
{$from/text()}
{$to/text()}
</result>
特定车辆访问的城市列表:
for $c in /transport/trips/trip/
where (data ($c/@ vehicle)=""PKR856"")
<result2>
{$c/from/text()}
{$c/to/text()}
</result2>
如果有人可以帮我减去这些清单,我感激不尽。
答案 0 :(得分:1)
假设您将城市作为字符串序列,请使用谓词和=
的集合语义来过滤所有访问过的城市:
let $cities := ("Munich", "Berlin", "Hamburg")
let $visited := ("Munich", "Frankfurt")
return $cities[not(. = $visited)]
将返回柏林和汉堡的城市。
如果左侧(此处:始终是一个城市)的任何元素与右侧的任何元素(所有访问过的城市)匹配,则 =
返回true。实现$cities[. != $visited]
因此会返回其他内容:!=
如果左侧的任何值与右侧的任何值都不匹配,则返回true。
答案 1 :(得分:1)
这甚至可以仅在XPath中完成。在以下代码段中,$driver-cities
将选择特定车辆访问过的所有城市名称。如果您的处理器不支持/(element, another-element)
语法,您也可以使用union运算符,即/trips/trip[@vehicle="PKR856"]/from | /trips/trip[@vehicle="PKR856"]/to
。
然后选择所有不在$driver-cities
序列中的城市,如Jens答案中所述。
let $driver-cities := /trips/trip[@vehicle="PKR856"]/(from, to, through)/string()
return /trips/trip/(from, to)/string()[not(. = $driver-cities)]