0

我正在尝试在此端点从 BNCF 检索结果。

我的查询(以“ab”为例)是:

PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?source ?label ?content
                WHERE {
                    ?source a skos:Concept;
                        skos:prefLabel ?label; 
                        skos:scopeNote ?content.
                FILTER regex(str(?label), "ab", "i")
            }

实际上,如果您尝试运行它,该查询是正确的。但是当我尝试从我的 python 获取结果时,这是错误:

SyntaxError: JSON Parse error: Unexpected EOF

这是我的python代码:

__3store = "http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query"
sparql = SPARQLUpdateStore(queryEndpoint=__3store)
sparql.setReturnFormat(JSON)
results = sparql.query(query_rdf).convert()
print json.dumps(result, separators=(',',':'))

我根据这个答案尝试了上面的代码,然后我的代码是这样的:

__3store = "http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query"
sparql = SPARQLWrapper(__3store,returnFormat="json")
sparql.setQuery(query_rdf)
result = sparql.query().convert() 
print json.dumps(result, separators=(',',':'))

但两者都抛出相同的错误。

有谁知道如何修理它?谢谢

编辑:

这是python代码,希望够看懂

import sys
sys.path.append ('cgi/lib')
import rdflib
from rdflib.plugins.stores.sparqlstore import SPARQLUpdateStore, SPARQLStore
import json
from SPARQLWrapper import SPARQLWrapper, JSON

#MAIN
print "Content-type: application/json"
print
prefix_SKOS =       "prefix skos:      <http://www.w3.org/2004/02/skos/core#>"
crlf = "\n"
query_rdf = ""
query_rdf += prefix_SKOS + crlf
query_rdf += '''
            SELECT DISTINCT ?source ?title ?content
                WHERE {
                    ?source a skos:Concept;
                        skos:prefLabel ?title; 
                        skos:scopeNote ?content.
                FILTER regex(str(?title), "ab", "i")
            }

        '''
__3store = "http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query"
sparql = SPARQLWrapper(__3store,returnFormat="json")
sparql.setQuery(query_rdf)
result = sparql.query().convert() 

print result

在 Python shell 中运行它会返回:

Content-type: application/json


Warning (from warnings module):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SPARQLWrapper-1.6.4-py2.7.egg/SPARQLWrapper/Wrapper.py", line 689
RuntimeWarning: Format requested was JSON, but XML (application/sparql-results+xml;charset=UTF-8) has been returned by the endpoint
<xml.dom.minidom.Document instance at 0x105add710>

因此,如果我将 Json 指定为返回格式,我认为结果也始终是 XML。

4

1 回答 1

0

这里有几个问题:

首先,SPARQLUpdateStore如果你想通过 rdflib 的 Graph 接口访问 SPARQL 存储,你应该只使用 from rdflib(例如,你可以添加三元组,你可以迭代它们,等等)。如果您想自己编写 SPARQL 查询,您应该使用SPARQLWrapper.

其次,如果您要求 SPARQLWrapper 返回 JSON,它实际上是向服务器询问一些最常见和标准化的mime 类型,我们称之为“json”,如下所示

_SPARQL_JSON = ["application/sparql-results+json", "text/javascript", "application/json"]

似乎您的服务器确实了解application/sparql-results+json,但不是组合的“给我任何这些 mime-types 标头”,因为 rdflib 编译它以获得最大的互操作性(因此您的服务器基本上不完全支持HTTP Accept Headers):

curl -i -G -H 'Accept: application/sparql-results+json' --data-urlencode 'query=PREFIX skos: 
<http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?source ?label ?content
WHERE {
 ?source a skos:Concept;
 skos:prefLabel ?label;
 skos:scopeNote ?content.
 FILTER regex(str(?label), "ab", "i")
}' http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query

将返回:

HTTP/1.1 200 OK
Date: Mon, 18 May 2015 13:13:45 GMT
Server: Apache/2.2.17 (Unix) PHP/5.3.6 mod_jk/1.2.31
...
Content-Type: application/sparql-results+json;charset=UTF-8

{
  "head" : {
    "vars" : [ ],
    "vars" : [ "source", "label", "content" ],
    "link" : [ "info" ]
  },
  "results" : {
    "bindings" : [ {
      "content" : {
        "type" : "literal",
        "value" : "Il lasciare ingiustificatamente qualcuno o qualcosa di cui si è responsabili"
      },
      "source" : {
        "type" : "uri",
        "value" : "http://purl.org/bncf/tid/12445"
      },
      "label" : {
        "xml:lang" : "it",
        "type" : "literal",
        "value" : "Abbandono"
      }
    },
...

所以一切都很好,但如果我们要求组合的、更具互操作性的 mime 类型:

curl -i -G -H 'Accept: application/sparql-results+json,text/javascript,application/json' --data-urlencode 'query=PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?source ?label ?content
WHERE {
 ?source a skos:Concept;
 skos:prefLabel ?label;
 skos:scopeNote ?content.
 FILTER regex(str(?label), "ab", "i")
}' http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query

我们得到一个 xml 结果:

HTTP/1.1 200 OK
Server: Apache/2.2.17 (Unix) PHP/5.3.6 mod_jk/1.2.31
...
Content-Type: application/sparql-results+xml;charset=UTF-8

<?xml version='1.0' encoding='UTF-8'?>
...

长话短说:这是您正在使用的服务器中的一个错误。以下是一个令人讨厌的解决方法(似乎 SPARQLWrapper 不仅允许我们手动设置标题,而是无条件地覆盖它们_createRequest),但它有效:

In [1]: import SPARQLWrapper as sw

In [2]: sparql = sw.SPARQLWrapper("http://digitale.bncf.firenze.sbn.it/openrdf-workbench/repositories/NS_03_2014/query")

In [3]: sparql.setReturnFormat(sw.JSON)

In [4]: sparql.setQuery('''                                                                                                     PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?source ?label ?content
                WHERE {
                    ?source a skos:Concept;
                        skos:prefLabel ?label;
                        skos:scopeNote ?content.
                FILTER regex(str(?label), "ab", "i")
            }
''')

In [5]: request = sparql._createRequest()

In [6]: request.add_header('Accept', 'application/sparql-results+json')

In [7]: from urllib2 import urlopen

In [8]: response = urlopen(request)

In [9]: res = sw.Wrapper.QueryResult((response, sparql.returnFormat))

In [10]: result = res.convert()

In [11]: result
Out[11]:
{u'head': {u'link': [u'info'], u'vars': [u'source', u'label', u'content']},
 u'results': {u'bindings': [{u'content': {u'type': u'literal',
     u'value': u'Il lasciare ingiustificatamente qualcuno o qualcosa di cui si \xe8 responsabili'},
    u'label': {u'type': u'literal',
     u'value': u'Abbandono',
     u'xml:lang': u'it'},
    u'source': {u'type': u'uri', u'value': u'http://purl.org/bncf/tid/12445'}},
   ...
于 2015-05-18T14:33:34.737 回答