如何使用SPARQL从Wikidata获取属性标签

如何使用SPARQL从Wikidata获取属性标签,sparql,wikidata,sparqlwrapper,Sparql,Wikidata,Sparqlwrapper,我正在使用SPARQLWrapper将SPARQL查询发送到Wikidata。 目前,我正在尝试查找实体的所有属性。例如,使用一个简单的元组,例如:wd:Q11663?a?b.这本身就是有效的,但我正在尝试为返回的属性和实体寻找人类可读的标签 虽然服务wikibase:label使用Wikidata的GUI界面工作,但这不适用于SPARQLWrapper,SPARQLWrapper坚持为变量及其“label”返回相同的值 查询属性rdfs:label适用于实体(?b),但这种方法不适用于属性(?

我正在使用SPARQLWrapper将SPARQL查询发送到Wikidata。 目前,我正在尝试查找实体的所有属性。例如,使用一个简单的元组,例如:
wd:Q11663?a?b.
这本身就是有效的,但我正在尝试为返回的属性和实体寻找人类可读的标签

虽然
服务wikibase:label
使用Wikidata的GUI界面工作,但这不适用于SPARQLWrapper,SPARQLWrapper坚持为变量及其“label”返回相同的值

查询属性
rdfs:label
适用于实体(?b),但这种方法不适用于属性(?a)

属性似乎是作为完整URI返回的,如
http://www.wikidata.org/prop/direct/P1536
。使用GUI,我可以成功地查询
wd:P1536?a?b.
。如果我将其作为第二个查询发送,则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.
   }
""")
那么,如何在一个查询中获得属性的标签(哪个应该更有效)


[旁白:是的,我对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 .
}
此代码还包括从标签(“天气”)到查询实体(
?项
)的查找

服务正在工作,但是如果没有
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
时返回结果。添加可选项将返回结果,即使没有定义标签。

您的查询有点混乱。您说过它不适用于标签服务,但您使用了
#prop wikibase:directClaim?p
,而在上面的三重模式中,该属性被称为
?a
。这确实行不通。您还必须放置类似于
?b rdfs:label?bLabel的内容。过滤(lang(?bLabel)=“en”)。
到一个
可选的
子句中,否则您将不会得到任何没有标签的文本值。行
BIND(strafter(str(?a),“prop/direct/”)作为propLabel)。
使
propLabel
成为一个简单的字符串文本,因此,
?propLabel rdfs:label?aLabel
无法工作。我的建议:
选择?a?propLabel?b?bLabel,其中{wd:Q11663?a?b.服务wikibase:label{bd:serviceParam wikibase:language“en”。}?prop wikibase:directClaim?a.}
@AKSW:是的,对我们大家来说都有点困惑-我在学习SPARQL:-)的早期阶段。我对directClaim一点也没有尝试,因为服务线没有与SPARQLWrapper一起工作。我刚刚尝试了你的建议,看起来很有效-谢谢。我需要阅读directClaim等。关于字符串文字:我想知道这是否是这是怎么回事,但我找不到将字符串文字转换为元素的方法。如何在不依赖Wikidata扩展的情况下以通用/标准SPARQL的方式获取属性标签?@AKSW:好的,我已经将您的代码与我的代码进行了比较。我相信我现在明白了发生了什么-谢谢!它看起来像是标签服务如果找不到任何东西,则默认为实体值-因此结果看起来很混乱,返回的实体名称和标签完全相同。实际上有些是,有些不是。将可选项添加到rdfs:label子句中突出显示了这一点。我现在也理解了wikibase:directClaim-非常简单!欢迎发布它作为一个答案,或者我可以发布一个带有我的代码的答案和我理解的解释。