Запрос SPARQL с файлом Turtle (общедоступный источник данных)

Я новичок в файлах формата Turtle и запрашиваю их с помощью SPARQL. Так что у меня есть много вопросов, которые нужно решить, надеюсь, вы мне поможете!

У меня есть файл под названием equipamentsCURT3.ttl, который содержит следующее:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix v: <http://www.w3.org/2006/vcard/ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://opendata.gencat.cat/recursos/equipaments/30883> a v:VCard ;
v:adr [ a v:Work ;
        v:country-name "Spain" ;
        v:locality "Sabadell" ;
        v:postal-code "08202" ;
        v:region "Vallès Occidental" ;
        v:street-address " c.  Sant Josep" ] ;
v:category "2. Parvulari"@ca,
    "3. Educació primària"@ca,
    "4. Educació secundària obligatòria"@ca,
    "Educació. Formació"@ca,
    "Ensenyaments de règim general"@ca ;
v:fn "Escolàpies Sabadell"@ca ;
v:geo [ v:latitude 4.154826e+01 ;
        v:longitude 2.111243e+00 ] ;
v:nickname "Escolàpies Sabadell"@ca ;
v:tel [ a v:Pref,
            v:Tel,
            v:Work ;
        rdf:value "937255348" ] .

<http://opendata.gencat.cat/recursos/equipaments/31264> a v:VCard ;
v:adr [ a v:Work ;
        v:country-name "Spain" ;
        v:locality "Molins de Rei" ;
        v:postal-code "08750" ;
        v:region "Baix Llobregat" ;
        v:street-address " c.  Ntra. Sra. de Lourdes" ] ;
v:category "4. Educació secundària obligatòria"@ca,
    "7. Batxillerat"@ca,
    "8. Cicles formatius d'FP de grau mitjà (CFPM)"@ca,
    "9. Cicles formatius d'FP de grau superior (CFPS)"@ca,
    "Educació. Formació"@ca,
    "Ensenyaments de règim general"@ca ;
v:fn "Institut Bernat el Ferrer"@ca ;
v:geo [ v:latitude 4.14105e+01 ;
        v:longitude 2.02704e+00 ] ;
v:nickname "Institut Bernat el Ferrer"@ca ;
v:tel [ a v:Pref,
            v:Tel,
            v:Work ;
        rdf:value "936683762" ] .

<http://opendata.gencat.cat/recursos/equipaments/31265> a v:VCard ;
v:adr [ a v:Work ;
        v:country-name "Spain" ;
        v:locality "Castellar del Vallès" ;
        v:postal-code "08211" ;
        v:region "Vallès Occidental" ;
        v:street-address " NC  Bonavista" ] ;
v:category "2. Parvulari"@ca,
    "3. Educació primària"@ca,
    "Educació. Formació"@ca,
    "Ensenyaments de règim general"@ca ;
v:fn "Escola Bonavista"@ca ;
v:geo [ v:latitude 4.161903e+01 ;
        v:longitude 2.091745e+00 ] ;
v:nickname "Escola Bonavista"@ca ;
v:tel [ a v:Pref,
            v:Tel,
            v:Work ;
        rdf:value "937144195" ] .

Я использую Python3.5 и библиотеку RDFLib (https://github.com/RDFLib/rdflib). Мне нужно прочитать файл с именем equipamentsCURT.rdf, сериализовать его в equipamentsCURT3.ttl, а затем получить всю информацию, относящуюся к оборудованию. Например, для оборудования 30883 (http://opendata.gencat.cat/recursos/equipaments/30883), я хочу v: adr, v: category, v: fn, v: geo и v: tel. Для получения этих данных я использую SPARQL, но не знаю, почему запрос не работает. Я очень запутался в том, как запрашивать информацию.

Вот мой код:

import rdflib , pprint
from rdflib import URIRef, Graph
from rdflib.plugins import sparql

g = Graph()
g.load("equipamentsCURT3.ttl", format='turtle')

queryTest = 'prefix v: <http://www.w3.org/2006/vcard/ns#> ' \
'select ?y where {?x  a <http://opendata.gencat.cat/recursos/equipaments 30883>; ?y v:VCard .}'
qresult = g.query(queryTest)

for st in qresult:
 print rdflib.term.Literal(st).value

person cmc_carlos    schedule 04.03.2017    source источник


Ответы (1)


Весь запрос не имеет смысла и не соответствует данным. Я бы посоветовал сначала прочитать учебник по SPARQL. Весь запрос выглядит как копипаст из чего-то еще + какой-то случайный материал с вашей стороны.

  1. URI http://opendata.gencat.cat/recursos/equipaments 30883 содержит неправильный пробел

  2. http://opendata.gencat.cat/recursos/equipaments/30883 не класс. Таким образом, тройной шаблон ?x a <http://opendata.gencat.cat/recursos/equipaments/30883>, который означает, что все ресурсы, принадлежащие к классу http://opendata.gencat.cat/recursos/equipaments/30883, не соответствуют вашим данным.

  3. Второй тройной образец - ?x ?y v:VCard. И вы выбираете предикат ?y в качестве окончательного результата вашего запроса. Но вам нужны объекты для данного субъекта и данного набора предикатов. Синтаксис тройки / соотв. тройной паттерн) субъект-предикат-объект. Таким образом, например, для v:category это должно быть

PREFIX v: <http://www.w3.org/2006/vcard/ns#> 
SELECT ?o WHERE {
  <http://opendata.gencat.cat/recursos/equipaments/30883>  v:category ?o 
}

Для других свойств это будет более сложным, поскольку сами значения являются пустыми узлами, к которым добавлено несколько значений через дополнительные свойства. Например. для v:adr это будет

PREFIX v: <http://www.w3.org/2006/vcard/ns#> 
SELECT ?p ?o WHERE {
  <http://opendata.gencat.cat/recursos/equipaments/30883>  v:adr ?adr .
  ?adr ?p ?o 
}

Обновлять

Если вам нужны не значения, а свойства, правильно иметь переменную в позиции предиката. Но неправильно ограничивать его теми свойствами, которые встречаются только в тройках с объектом v:VCard, потому что нет такого свойства, кроме rdf:type (a - это просто его синоним). В таком случае это должно быть

PREFIX v: <http://www.w3.org/2006/vcard/ns#> 
SELECT DISTINCT ?p WHERE {
  <http://opendata.gencat.cat/recursos/equipaments/30883>  ?p ?o 
}
person UninformedUser    schedule 04.03.2017
comment
Большое спасибо @AKSW. И последнее, и я отмечу ваш ответ как действительный для моей проблемы. В первом отправленном вами запросе я получил формат (rdflib.term.Literal (u'2. Parvulari ', lang = u'ca'),), это нормально, но если мне нужно только '2. Парвулари, что мне делать? - person cmc_carlos; 05.03.2017
comment
Вызов .value для объекта Literal должен возвращать лексическую форму, что в основном то, что вам нужно. - person UninformedUser; 05.03.2017
comment
.value не работает. У меня есть: для st в qresult: print rdflib.term.Literal (st) .value - person cmc_carlos; 05.03.2017
comment
Не могли бы вы обновить свой пример кода в вопросе, чтобы мы могли видеть весь код, который вы запускаете для анализа результата запроса? - person UninformedUser; 05.03.2017
comment
Сделанный! Но я не разбираю результат запроса ... :( - person cmc_carlos; 05.03.2017
comment
Под синтаксическим анализом я имел в виду обработку - в вашем случае вы повторяете набор результатов. print st['o'].toPython() или print st.o.toPython() должны работать - person UninformedUser; 05.03.2017
comment
Извините, AKSW, что мне делать, если я хочу получить v: tel с разных URI? Я имею в виду, что в файле 3 оборудования, что мне делать, чтобы получить v: tel с этого оборудования. На данный момент я знаю один URI, но для 3 ... я думаю о создании массива URI, а затем выполнить запрос, но я не знаю, как объединить массив с запросом. СПАСИБО! - person cmc_carlos; 05.03.2017
comment
Вы можете выбрать все экземпляры типа v:VCard в наборе данных или, если у вас есть заданный набор URI, вы можете использовать предложение SPARQL 1.1 VALUES: PREFIX v: <http://www.w3.org/2006/vcard/ns#> SELECT ?s ?o WHERE { VALUES ?s {<URI1> <URI2>} ?s v:tel ?o } - person UninformedUser; 06.03.2017
comment
Есть ли более автоматический способ сделать это? Я имею в виду, для 3 - это просто, но для 2000 URI будет безумием. - person cmc_carlos; 06.03.2017
comment
Как я уже сказал, если все они принадлежат к одному классу, как в ваших демонстрационных данных v:VCard, вы можете выбрать все экземпляры этого класса с помощью SPARQL. PREFIX v: <http://www.w3.org/2006/vcard/ns#> SELECT ?s ?o WHERE { ?s a v:VCard . ?s v:tel ?o } - person UninformedUser; 06.03.2017