XQuery - проверка, содержит ли один набор другой набор (получение нулевых результатов) - PullRequest
0 голосов
/ 04 мая 2018

Итак, я использую эту базу данных XML: https://www.dbis.informatik.uni -goettingen.de / Mondial / mondial.xml , и это описание моей проблемы:

"Какие страны являются членами ВСЕХ организаций, чьи имена начать со слова «международный» и со штаб-квартирой в Европе? »

Код Xquery:

let $doc := doc("mondial.xml")/mondial
let $countries := (
  for $c in $doc/country
  let $memShipsSet := $c/tokenize(data(@memberships), '\s')
  let $orgSet := $inter-orgs-eu/data(@id)
  where empty(distinct-values($orgSet[not(.=$memShipsSet)]))
  return <country code="{$c/data(@car_code)}">{$c/data(name)}</country>
)
return $countries

($inter-orgs-eu - это последовательность / список всех организаций [элементов], которые имеют в названии слово «Международный» и имеют штаб-квартиру в Европе)

Функция distinct-values($orgSet[not(.=$memShipsSet)]) возвращает значения в $orgSet, которые не отображаются в $memShipsSet (ref: http://www.xqueryfunctions.com/xq/functx_value-except.html)

Однако, когда я запускаю этот код, он просто возвращает ноль результатов, и я не могу понять, что я сделал неправильно. Это логическая ошибка или что-то еще (я новичок в Xquery, поэтому вполне может быть что-то очевидное, что я пропустил)?

Любая помощь приветствуется.

Спасибо!

EDIT: Полный код:

let $doc := doc("mondial.xml")/mondial

let $inter-orgs := (
  for $o in $doc/organization
  let $name := xs:string($o/data(name))
  where contains($name,xs:string("International"))
  return $o
)

let $inter-orgs-eu := (
  for $o in $inter-orgs
  let $hq := $o/data(@headq)
  let $city := $doc/country/id($hq)
  let $cCode := $city/data(@country)
  let $country := $doc/country[data(@car_code)=$cCode]
  where $country/encompassed/data(@continent) = 'europe'
  return $o
)

let $countries := (
  for $c in $doc/country
  let $memShipsSet := $c/tokenize(data(@memberships), '\s')
  let $orgSet := $inter-orgs-eu/data(@id)
  where empty(distinct-values($orgSet[not(.=$memShipsSet)]))
  return <country code="{$c/data(@car_code)}">{$c/data(name)}</country>
)
return $countries

1 Ответ

0 голосов
/ 06 мая 2018

Оказывается, что действительно есть 0 стран, которые являются членами ВСЕХ этих организаций. Так что мой код на самом деле работал отлично. Спасибо @MartinHonnen за создание таблицы всех стран и организаций ($ inter-orgs-eu), членом которой они являются на xqueryfiddle.liberty-development.net/jyyiVhg.

В моем коде была одна небольшая проблема, которую я сейчас исправил. $ inter-orgs возвращает все организации, которые содержат слово «International», но в соответствии с описанием проблемы он должен возвращать только те организации, которые НАЧИНАЮТСЯ со слова «International». Я исправил это, используя функцию starts-with в моем предложении where в $inter-orgs вместо использования функции contains. Это не имело никакого значения для моего конечного результата (когда я возвращаю $countries).

Финальный код:

let $doc := doc("mondial.xml")/mondial

let $inter-orgs := (
  for $o in $doc/organization
  let $name := xs:string($o/data(name))
  where starts-with($name,xs:string("International"))
  return $o
)

let $inter-orgs-eu := (
  for $o in $inter-orgs
  let $hq := $o/data(@headq)
  let $city := $doc/country/id($hq)
  let $cCode := $city/data(@country)
  let $country := $doc/country[data(@car_code)=$cCode]
  where $country/encompassed/data(@continent) = 'europe'
  return $o
)

let $countries := (
  for $c in $doc/country
  let $memShipsSet := $c/tokenize(data(@memberships), '\s')
  let $orgSet := $inter-orgs-eu/data(@id)
  let $orgsNotInMemSet := distinct-values($orgSet[not(.=$memShipsSet)])
  where empty($orgsNotInMemSet)
  return <country code="{$c/data(@car_code)}">{$c/data(name)}</country>
)

return <root>
 {$countries}
</root>
...