Почему мой запрос SPARQL возвращает URI ресурса вместо его имени?
Я хочу получить все классы моей онтологии. Это часть моего файла онтологии в формате RDF/XML, созданного Protege:
<!-- http://www.w3.org/2002/07/owl#aqua -->
<Class rdf:about="&owl;aqua"/>
<!-- http://www.w3.org/2002/07/owl#varioPerfect -->
<Class rdf:about="&owl;varioPerfect"/>
Я написал этот запрос, который правильно работает в Protege, но когда я использую его в dotNetRDF, он возвращает полный URI класса, а не только его имя.
public string[] ontologysearch()
{
List<string> list = new List<string>();
TripleStore store = new TripleStore();
Graph mygraph = new Graph();
mygraph.LoadFromFile("D:/msc/search-engine/project/catalogXML.owl");
store.Add(mygraph);
string sparqlQuery1 = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
+ "PREFIX owl: <http://www.w3.org/2002/07/owl#>"
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
+ "SELECT distinct ?cls1"
+ " WHERE{"
+ " ?cls1 a owl:Class .}";
SparqlQueryParser sparqlParser = new SparqlQueryParser();
SparqlQuery query = sparqlParser.ParseFromString(sparqlQuery1);
InMemoryDataset ds = new InMemoryDataset(mygraph);
//Get the Query processor
ISparqlQueryProcessor processor = new LeviathanQueryProcessor(ds);
Object results = processor.ProcessQuery(query);
if (results is SparqlResultSet)
{
SparqlResultSet r = results as SparqlResultSet;
foreach (SparqlResult res in r)
{
list.Add(res["cls1"].ToString());
}
}
return list.ToArray();
}
Результат, который я ожидал, был просто "аква", но на самом деле это " http://www.w3.org/2002/07/owl". Почему это происходит, и как я могу получить имя вместо этого?
1 ответ
Неанонимные ресурсы в RDF и OWL идентифицируются IRI. Ваша онтология ясно говорит, что http://www.w3.org/2002/07/owl#aqua - это класс. Если вы попросите урок, это то, что вы должны получить. Возможно, что Protege удаляет часть http://www.w3.org/2002/07/owl#, когда отображает результат, но результат по-прежнему на самом деле IRI.
Примечание: вам действительно не следует определять новые классы, чьи IRI начинаются со стандартного пространства имен OWL. Вы должны определить свой собственный префикс, обычно связанный с IRI онтологии.
Если вы просто хотите получить в результате строку "aqua", у вас есть два варианта. Первый (и предпочтительный) подход заключается в получении метки rdfs: класса, если он есть, который должен быть строковым именем класса. Если по какой-то причине это не работает, вы можете взять строковое значение URI и удалить строковое значение префикса. Вот примеры обоих подходов к конечной точке DBpedia SPARQL:
select ?class ?label where {
?class a owl:Class ; rdfs:label ?label
filter langMatches(lang(?label),'en')
}
limit 10
Результаты SPARQL (с меткой rdfs:)
select ?class ?name where {
?class a owl:Class
bind(strafter(str(?class),str(dbpedia-owl:)) as ?name)
}
limit 10
Результаты SPARQL (путем удаления префикса)
Удаление префикса URI для целей отображения, как правило, не рекомендуется, поскольку предполагается, что URI имеет удобочитаемую форму. В случае с DBPedia это работает, но множество наборов данных имеют URI с внутренними кодами, а не с понятными для человека именами. Так что если rdfs:label
(которое явно определено как удобочитаемое представление ресурса), вы должны стараться и всегда использовать это.