如果我的查询返回的 Wikidata 资源在我过滤的语言中没有可用标签,我得到一个空单元格。
SELECT *
WHERE
{
?country wdt:P31 wd:Q6256.
?country rdfs:label ?country_name
FILTER(LANG(?country_name) = 'jbo').
}
如果第一种语言失败,如何请求以任何一种可用语言返回标签?
如果我的查询返回的 Wikidata 资源在我过滤的语言中没有可用标签,我得到一个空单元格。
SELECT *
WHERE
{
?country wdt:P31 wd:Q6256.
?country rdfs:label ?country_name
FILTER(LANG(?country_name) = 'jbo').
}
如果第一种语言失败,如何请求以任何一种可用语言返回标签?
首先,首选langMatches来检查语言标签。这在您的情况下尤其重要,因为您可能想要一个英文标签,而langMatches(lang(?label), "en")将找到一个带有标签“en”或“en-GB”的标签" 或 "en-US" 等。这些是该语言的区域变体,而langMatches可以帮助您找到它们。
@svick 在评论中注意到,原始解决方案的最终结果是英语名称与非英语名称的笛卡尔积中的每个元素都有一行。您可以通过使用select distinct来避免这种情况。但是真的有更好的办法:在两个optional中使用同一个变量;第一个检查英文标签,第二个检查非英文标签。如果第一个成功,则第二个永远不会被调用。也就是说,只需执行以下操作:
select ?country ?label {
?country wdt:P31 wd:Q6256
optional {
?country rdfs:label ?label
filter langMatches(lang(?label), "en")
}
optional {
?country rdfs:label ?label
}
}
不过,在那之后,coalesce会做你想做的事。它接受多个参数,并返回第一个有值的参数。因此,您可以在可选块中匹配首选语言,在另一个块中匹配任何语言,然后合并这些值:
select distinct ?country (coalesce(?enLabel, ?anyLabel) as ?label) {
?country wdt:P31 wd:Q6256
optional {
?country rdfs:label ?enLabel
filter langMatches(lang(?enLabel), "en")
}
optional {
?country rdfs:label ?anyLabel
}
}