问题描述
我使用SPARQLWrapper向Wikidata发送SPARQL查询。目前,我正在尝试查找实体的所有属性。例如。使用简单的元组(如:wd:Q11663 ?a ?b.
),这本身就可以工作,但我正在尝试为返回的属性和实体找到人类可读的标签。
虽然SERVICE wikibase:label
使用Wikidata的GUI界面工作,但这不适用于SPARQLWrapper-它坚持为变量及其"label"返回相同的值。
对属性rdfs:label
的查询适用于实体(?B),但此方法不适用于属性(?A)。
该属性似乎是以完整URI的形式返回的,例如http://www.wikidata.org/prop/direct/P1536
。使用GUI,我可以成功查询wd:P1536 ?a ?b.
。如果我将SPARQLWrapper作为第二个查询(但不是在第一个查询中)发送,则此操作适用于SPARQLWrapper。
以下是我的代码:
from SPARQLWrapper import SPARQLWrapper, JSON
sparql = SPARQLWrapper("http://query.wikidata.org/sparql")
sparql.setQuery("""
SELECT ?a ?aLabel ?propLabel ?b ?bLabel
WHERE
{
wd:Q11663 ?a ?b.
# Doesn't work with SPARQLWrapper
#SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
#?prop wikibase:directClaim ?p
# but this does (and is more portable)
?b rdfs:label ?bLabel. filter(lang(?bLabel) = "en").
# doesn't work
#?a rdfs:label ?aLabel.
# property code can be extracted successfully
BIND( strafter(str(?a), "prop/direct/") AS ?propLabel).
#BIND( CONCAT("wd:", strafter(str(?a), "prop/direct/") ) AS ?propLabel).
# No matches, even if I concat 'wd:' to ?propLabel
?propLabel rdfs:label ?aLabel
# generic search for any properties also fails
#?propLabel ?zz ?aLabel.
}
""")
# However, this returns a label for P1536 - which is one of wd:Q11663's properties
sparql.setQuery("""SELECT ?b WHERE
{
wd:P1536 rdfs:label ?b.
}
""")
那么,如何在一个查询中获取属性的标签(应该更高效)?
[旁白:是的,我有点粗鲁&&ANP;准备好了EN过滤-如果拿不到任何东西,经常会把它掉在地上]
推荐答案
我在使用两种方法时遇到了问题-上面的代码混合了这两种方法。此外,SPARQLWrapper在这里也不是问题。
使用wikibase标签服务的第一种方法应该如下所示:
SELECT ?a ?aLabel ?propLabel ?b ?bLabel
WHERE
{
?item rdfs:label "weather"@en.
?item ?a ?b.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
?prop wikibase:directClaim ?a .
}
此代码还包括从标签(‘weet’)到查询实体(?item
)的查找。
rdfs:label
定义,则它只返回实体。GUI和SPARQLWrapper(到SPARQL端点)只是以不同的顺序返回结果-所以看起来我看到了很多"失败"的输出(即。实体和失败标签都报告为相同)。当我开始向下面的方法添加可选子句时,这一点变得清晰起来。
?prop wikibase:directClaim ?a .
行非常简单。Wikibase定义directClaim
将属性映射到实体。然后,这允许它定义关于属性的元组(即,标签)。许多其他本体只是使用相同的标识符。
我的第二种方法(更通用的方法)是您在许多书籍和在线教程中找到的方法。这里的问题是,wikibase的属性中有完整的URL,我需要将它们转换为实体。我尝试了字符串操作,但这会产生一个字符串文字,而不是一个实体。解决方案是再次使用directClaim
:
?prop wikibase:directClaim ?a .
?prop rdfs:label ?propLabel. filter(lang(?propLabel) = "en").
请注意,只有在定义了rdfs:label
时才会返回结果。即使未定义标签,添加可选选项也会返回结果。 这篇关于如何使用SPARQL从维基数据获取属性标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!