2014-06-09 43 views
0

我有以下的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> 

我已經試過這還不算workoing :

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

你能提供一個例子文件? '$ c'和'$ v'是相同的,所以'$ c除了$ v'將一直是空的。你的原始查詢有什麼不同? –

+0

@LeoWörteler我編輯並添加了我的XML文件。 – Bernard

回答

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> 
+0

感謝您的回答,但這是返回不是由特定車輛完成的旅行。我關心的是城市的名稱不被特定的車輛訪問。 – Bernard

+0

這可能是我需要的,但我得到的錯誤: $ c /(from | to | through)/ string()除$ v /(from | to | through)/ string() – Bernard

+0

您會收到一個錯誤,因爲除了'對節點序列進行操作,而不是對原子類型序列(例如字符串)進行操作。 – adamretter

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,下面的查詢可能是效率較低,但計算結果相同。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 
相關問題