带有子字符串的字符串的 XQuery

XQuery on string with substrings

这是我正在使用的数据库中的代码示例:

<mondial>
<mountain id="mount-Sajama" country="BOL" type="volcano">
<name>Sajama</name>
<mountains>Andes</mountains>
<located country="BOL" province="prov-BOL-2"/>
<elevation>6542</elevation>
<longitude>-68.9</longitude>
<latitude>-18.1</latitude>
</mountain>
<mountain id="mount-Licancabur" country="BOL RCH" type="volcano">
<name>Licancabur</name>
<mountains>Andes</mountains>
<located country="BOL" province="prov-BOL-3"/>
<located country="RCH" province="prov-Chile-2"/>
<elevation>5920</elevation>
<longitude>-67.9</longitude>
<latitude>-22.8</latitude>
</mountain>
<country car_code="N" area="324220" capital="cty-Norway-Oslo" memberships="org-AfDB org-AsDB org-BIS org-CE org-CBSS org-CCC org-ECE org-EBRD org-EFTA org-CERN org-ESA org-FAO org-IADB org-IAEA org-IBRD org-ICC org-ICAO org-ICFTU org-Interpol org-IDA org-IEA org-IFRCS org-IFC org-IFAD org-ILO org-IMO org-Inmarsat org-IMF org-IOC org-IOM org-ISO org-ICRM org-ITU org-Intelsat org-MTCR org-NAM org-NC org-NIB org-ANC org-NATO org-EN org-NSG org-OECD org-OSCE org-PCA org-UN org-UNAVEM-III org-UNCRO org-UNESCO org-UNIDO org-UNITAR org-UNIFIL org-MINURSO org-UNHCR org-UNPREDEP org-UNPROFOR org-UNTSO org-UPU org-WEU org-WHO org-WIPO org-WMO org-WTrO org-ZC">
<name>Norway</name>
<population>4383807</population>
<population_growth>0.48</population_growth>
<infant_mortality>4.9</infant_mortality>
<gdp_total>106200</gdp_total>
<gdp_agri>2.9</gdp_agri>
<gdp_ind>34.7</gdp_ind>
<gdp_serv>62.4</gdp_serv>
<inflation>2.5</inflation>
<indep_date from="S">1905-10-26</indep_date>
<government>constitutional monarchy</government>
<encompassed continent="europe" percentage="100"/>
<ethnicgroup percentage="82.5">Norwegian</ethnicgroup>
<ethnicgroup percentage="1.5">Sami</ethnicgroup>
<religion percentage="86.7">Protestant</religion>
<religion percentage="1">Roman Catholic</religion>
<religion percentage="1.8">Muslim</religion>
<language percentage="99">Norwegian</language>
<border country="R" length="167"/>
<border country="SF" length="729"/>
<border country="S" length="1619"/>
<province id="lteil-OS-N" capital="cty-Norway-Oslo" country="N">
<name>Oslo</name>
<population>449337</population>
<city id="cty-Norway-Oslo" is_country_cap="yes" is_state_cap="yes" country="N" province="lteil-OS-N">
<name>Oslo</name>
<longitude>10.7333</longitude>
<latitude>59.9333</latitude>
<population year="87">449337</population>
<located_at watertype="sea" sea="sea-Skagerrak"/>
</city>
</province>
<province id="lteil-AK-N" capital="cty-Norway-Oslo" country="N">
<name>Akershus</name>
<population>393217</population>
</province>
</mondial>

您可以在此处找到完整的 XML 文件: https://www.kth.se/social/files/54f4817bf27654358032133f/mondial.xml

我自己遇到了一些问题,因为在我的数据库中存在国家代码(car_codes 在 Country 和 country in Mountain),其中多个国家可以用与您相同的山区代码编写可以在mount-Licancabur中看到一个例子。

所以现在我想select每个大陆的最高山峰所以我写了下面的代码:

let $mondial := db:open('mondial')
for $country in $mondial/mondial/country/encompassed/@continent
for $mountains in $mondial/mondial/mountain
where contains($country/../../@car_code, $mountains/@country)

(: Tokenize ev för att lösa berg i två länder :)
let $elevation := $mountains/elevation
group by $country

return ($country, max($elevation))

这给出了输出:

europe
5642
asia
8167
africa
5895
australia
5775
america
6962

这些乍一看似乎是正确的,但珠穆朗玛峰应该是亚洲最大的山峰,高度为 8848 米。

所以我的问题是,我怎样才能与 car_code/country 中有两个国家代码的国家代码进行比较?我一直在阅读一些关于标记化的内容,但到目前为止还没有成功。

希望有人能帮助我,我被困了一段时间:)

通过阅读您的问题并查看 xml,您似乎正在尝试解决如下所示的挂载元素问题:

<mountain id="mount-Matterhorn" country="CH I">
 <name>Matterhorn</name>
 <mountains>Alps</mountains>
 <located country="CH" province="prov-Switzerland-24"/>
 <located country="I" province="prov-Italy-9"/>
 <elevation>4478</elevation>
 <longitude>7.56</longitude>
 <latitude>46</latitude>
</mountain>

@country 包含多个国家。

您可以通过将 where 更改为此来使用 tokenize 来做到这一点

where $mountains[tokenize(@country, " ") eq $country/../../@car_code]

您在此处执行的操作存在一些性能问题。每个山区元素都将针对每个国家进行标记化。这可以写得更高效,如果你愿意,我可以和你一起讨论。

更新:

这是另一种方法,可以让您到达每个大陆的最高海拔。使用 XML 的方式,你必须在山上使用标记化来比较县,但至少这样它只对每个大陆的每座山进行比较。

for $continent in fn:distinct-values($mondial/mondial/country/encompassed/@continent)
let $counties := $mondial/mondial/country[encompassed/@continent eq $continent]/@car_code
let $highest :=
(
    for $elevation in $mondial/mondial/mountain[fn:tokenize(@country, " ") = $counties]/elevation/text()
    order by xs:int($elevation) descending
    return $elevation
)[1]
return ($continent, $highest)

输出是

europe
7010
asia
8848
africa
5895
australia
4884
america
6962