简单的SPARQL查询,用于检索具有特定值的OWL类个体

时间:2014-04-27 17:13:16

标签: xml rdf sparql owl

我有两个人参加以下OWL课程:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
  <!ENTITY owl "http://www.w3.org/2002/07/owl#">
  <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
  <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
]>

<rdf:RDF xmlns="http://www.example.org/message#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">

  <owl:Ontology rdf:about="">
    <rdfs:comment>The Common Alerting Protocol Ontology</rdfs:comment>
    <rdfs:label>CAP Ontology</rdfs:label> 
  </owl:Ontology>

  <owl:Class rdf:ID="Message">
    <rdfs:label>CAP alert message</rdfs:label>
    <rdfs:comment>...</rdfs:comment>
  </owl:Class>

  <owl:Class rdf:ID="AlertStatus">
    <owl:oneOf rdf:parseType="Collection">
      <owl:Thing rdf:about="#Actual" />
      <owl:Thing rdf:about="#Exercise" />
      <owl:Thing rdf:about="#System" />
      <owl:Thing rdf:about="#Test" />
      <owl:Thing rdf:about="#Draft" />
    </owl:oneOf>
  </owl:Class>

  <owl:DatatypeProperty rdf:ID="hasSender">
    <rdfs:domain rdf:resource="#Message" />
    <rdfs:range rdf:resource="&xsd;string" />
  </owl:DatatypeProperty>  

  <owl:ObjectProperty rdf:ID="hasStatus">
    <rdfs:domain rdf:resource="#Message"/>
    <rdfs:range rdf:resource="#AlertStatus"/>
  </owl:ObjectProperty>

  <Message rdf:ID="KSTO1055887203">
    <hasSender>KSTO</hasSender>
    <hasStatus rdf:resource="#Actual"/>
  </Message>

  <Message rdf:ID="KAR0-0306112239-SW">
    <hasSender>KARO</hasSender>
    <hasStatus rdf:resource="#Actual"/>
  </Message>

</rdf:RDF>

如果我查询:

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender ?object }

,我明白了:

----------------------------------
| subject              |  object |
==================================
| KAR0-0306112239-SW   | "KARO"@ |
| KSTO1055887203       | "KSTO"@ |
----------------------------------

当我尝试仅检索hasSender值为“KARO”的消息时:

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"}

,查询不返回任何结果。我的RDF / OWL是否有任何问题。我错过了一个命名空间还是什么?

编辑:我使用Protege v4.3.0并且无论是否启动推理器(HermiT)都没有结果。我还编辑了第一个查询的输出。有一个尾随的'@'符号,我不确定它是否有任何意义。我没有在任何地方声明所涉及的字符串的语言(我提到这个原因我的理解是@符号用于声明字符串的语言,如"KARO"@en)。

1 个答案:

答案 0 :(得分:2)

您没有使用绝对IRI

如果在Turtle或N3序列化中查看数据,通常更容易找出要写入的正确SPARQL查询,因为这些序列化更接近SPARQL查询的语法。在这种情况下,您的数据是:

@prefix :      <http://www.example.org/message#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#System>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message>
        a             owl:Class ;
        rdfs:comment  "..." ;
        rdfs:label    "CAP alert message" .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#hasStatus>
        a            owl:ObjectProperty ;
        rdfs:domain  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message> ;
        rdfs:range   <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#AlertStatus> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Draft>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#KAR0-0306112239-SW>
        a           :Message ;
        :hasSender  "KARO" ;
        :hasStatus  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Exercise>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf>
        a             owl:Ontology ;
        rdfs:comment  "The Common Alerting Protocol Ontology" ;
        rdfs:label    "CAP Ontology" .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#KSTO1055887203>
        a           :Message ;
        :hasSender  "KSTO" ;
        :hasStatus  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#hasSender>
        a            owl:DatatypeProperty ;
        rdfs:domain  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message> ;
        rdfs:range   xsd:string .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Test>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#AlertStatus>
        a          owl:Class ;
        owl:oneOf  ( <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Exercise> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#System> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Test> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Draft> ) .

现在,值得指出可能没有文件:file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf,因此在您的数据中看到它可能会令人惊讶。问题在于原始数据中没有声明XML基础,因此您获得的实际IRI是不明确的,在这种情况下,取决于数据实际所在的位置。

在RDF / XML序列化中,您可以提供具有xml:base属性的XML库。在你的情况下,它会是这样的:

<rdf:RDF xmlns="http://www.example.org/message#"
         xml:base="http://www.example.org/message#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">

前缀少xmlns用作无前缀元素名称的前缀,但您仍需要一个XML库来解析元素上的rdf:about属性。

查询结果

即使使用这些相对IRI,我仍然会对您的查询产生结果。使用Jena的命令行sparql工具,我得到以下搜索结果:


PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender ?object }
------------------------------------------
| subject                       | object |
==========================================
| <data.rdf#KAR0-0306112239-SW> | "KARO" |
| <data.rdf#KSTO1055887203>     | "KSTO" |
------------------------------------------

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"}
---------------------------------
| subject                       |
=================================
| <data.rdf#KAR0-0306112239-SW> |
---------------------------------

编辑之后,我仍然不太确定发生了什么,但是RDF中带有语言标签的文字被编写为字符串形式,后跟@后跟语言标记。例如,

"Joshua"@en
"Giosuè"@it

如果您看到的结果看起来像这样,但我没有实际的语言标签,我不确定这意味着什么。也许您有一些带有语言标签的文字,但其中语言标签是空字符串。在任何情况下,您都可以通过更改查询来匹配这些案例,以查找词法格式为"KARO"的文字:

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE {
  ?subject foo:hasSender ?sender .
 filter( str(?sender) = "KARO" )
}

这不应该对您向我们展示的数据产生影响,但如果您完全修改了它(就像您对查询的输出所做的那样),则可能会解决您的问题。我知道,Protégé中的SPARQL查询功能也不会对您提供的输入文件执行查询,而是在其写出的另一个临时文件上运行查询。这可能会增加一些空语言标签。

可能的推理者互动

根据您正在查看结果的内容,我认为由于这些值是相对IRI,您可能会尝试以某种需要绝对IRI的方式显示它们。 (我不知道这样的方式会是什么,但我不了解你的设置。)

如果您使用的是OWL推理器,那么推理器提供给查询引擎的数据也可能与您在文件中看到的数据不同。正如AndyS在评论中指出的那样,因为hasSender属性的范围被声明为xsd:string,所以可能是推理者正在使用三元组

<data.rdf#KAR0-0306112239-SW> hasSender "KARO" 

并将其转换为

<data.rdf#KAR0-0306112239-SW> hasSender "KARO"^^xsd:string

对你而言,在这种情况下你需要使用查询

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"^^xsd:string }