【问题标题】:Why does my SPARQL query return the URI of a resource instead of its name?为什么我的 SPARQL 查询返回资源的 URI 而不是其名称?
【发布时间】:2015-04-13 07:15:17
【问题描述】:

我想获得我的本体的所有类别。这是 Protege 创建的 RDF/XML 格式的本体文件的一部分:

<!-- 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();

}

我预期的结果只是“aqua”,但实际上是“http://www.w3.org/2002/07/owl#aqua”。为什么会发生这种情况,我该如何取而代之取回名称?

【问题讨论】:

    标签: sparql dotnetrdf


    【解决方案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:label,如果有的话,它应该是类的字符串名称。如果由于某种原因不起作用,您可以获取 URI 的字符串值并去掉前缀的字符串值。以下是 DBpedia SPARQL 端点上两种方法的示例:

    select ?class ?label where {
      ?class a owl:Class ; rdfs:label ?label
      filter langMatches(lang(?label),'en')
    }
    limit 10
    

    SPARQL results (with rdfs:label)

    select ?class ?name where {
      ?class a owl:Class
      bind(strafter(str(?class),str(dbpedia-owl:)) as ?name)
    }
    limit 10
    

    SPARQL results (by stripping the prefix)

    为了显示目的而去除 URI 的前缀通常是不推荐的做法,因为它假定 URI 具有人类可读的形式。在 DBPedia 的情况下,它恰好可以工作,但大量数据集的 URI 带有内部代码,而不是人类可读的名称。因此,如果rdfs:label(明确定义为资源的人类可读表示)可用,您应该尝试并始终使用它。

    【讨论】:

    • 像往常一样非常彻底。补充一点:应该注意,为了显示目的而去除 IRI 的前缀通常不是推荐的做法,因为它假定 IRI 具有人类可读的形式。在 DBPedia 的情况下,它恰好可以工作,但大量数据集的 IRI 具有内部代码,而不是人类可读的名称。因此,如果rdfs:label明确定义为资源的人类可读表示)可用,您应该尝试并始终使用它。
    • @JeenBroekstra 同意。看来 OP 正在使用 Protege,虽然最新版本可能会采用用户提供的名称并自动创建 rdfs:label,但早期版本只是将名称与本体 IRI 连接起来。如果是这样,那么前缀剥离版本将更有用。也就是说,我同意 rdfs:label 版本是更好的做法,因为 IRI 确实应该被视为不透明的。
    • 非常感谢大家。但是第二个解决方案对我不起作用!经过所有的更改和努力,它出现了“未知函数 strafter ...”的错误。但标签很好。
    • @zafy strafter 在 SPARQL 1.1 中可用。如果您使用的是第一个版本 (SPARQL 1.0),则需要改用 regex
    猜你喜欢
    • 1970-01-01
    • 2016-05-06
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多