检索每个OWL的unionOf和intersectionOf的集合

时间:2013-10-22 17:47:15

标签: sparql jena owl

我正在尝试在OWL文件中提取intersectionOfunionOf,其中interesctionOfunionOf由类集合someValuesFrom或/组成和onProperty。我创建了一个SPARQL查询,它提取intersectionOf的“集合”,但问题是某些检索到的数据与该类无关。

例如,我有一个名为man的课程。这个类有一个等价的类,它是三个类的intersectionOf,即adultpersonmale。我的SPARQL查询返回一些不正确的结果:它返回类adultpersonmale等同于类man(即,这部分是正确的),但它们也是我的OWL中所有其他类的等效类文件如haulage_worker,这是不正确的。这是我的SPARQL查询:

PREFIX abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
PREFIX ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX mno: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>

SELECT  Distinct ?class ?equivalentClass  
WHERE{ ?class a owl:Class .
FILTER( STRSTARTS(STR(?class),"http://www.w3.org/2002/07/owl#") || STRSTARTS(STR(?class),"http://owl.cs.manchester.ac.uk/2009/07/sssw/people#") 

)

     ?x a owl:Class ; owl:intersectionOf ?list .
     ?list rdf:rest*/rdf:first ?equivalentClass .


   } GROUP BY ?class ?equivalentClass ORDER BY ?no

这是我的OWL文件:

<?xml version="1.0"?>
<rdf:RDF
    xmlns="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:ns0="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
  xml:base="http://owl.cs.manchester.ac.uk/2009/07/sssw/people">
  <owl:Ontology rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people"/>
  <owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing"/>
  <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_worker">
    <rdfs:comment rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
   ></rdfs:comment>
    <owl:equivalentClass>
      <owl:Restriction>
        <owl:onProperty>
          <owl:ObjectProperty      rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#works_for"/>
        </owl:onProperty>
        <owl:someValuesFrom>
        <owl:Class>
            <owl:unionOf rdf:parseType="Collection">
              <owl:Restriction>
               <owl:onProperty>
                <owl:ObjectProperty    rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#part_of"/>
               </owl:onProperty>
               <owl:someValuesFrom>
                <owl:Class   rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
               </owl:someValuesFrom>
              </owl:Restriction>
              <owl:Class   rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
            </owl:unionOf>
          </owl:Class>
         </owl:someValuesFrom>
        </owl:Restriction>
     </owl:equivalentClass>
    <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
    >haulage worker</rdfs:label>
  </owl:Class>
  <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#man">
    <owl:equivalentClass>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#adult"/>
          <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#person"/>
          <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#male"/>
        </owl:intersectionOf>
      </owl:Class>
    </owl:equivalentClass>
  </owl:Class>
</rdf:RDF>

这是我得到的输出(它们输出不正确):

-----------------------------------------
    | class               | equivalentClass |
    =========================================
    | abc:adult           | abc:adult       |
    | abc:adult           | abc:male        |
    | abc:adult           | abc:person      |
    | abc:haulage_company | abc:adult       |
    | abc:haulage_company | abc:male        |
    | abc:haulage_company | abc:person      |
    | abc:haulage_worker  | abc:adult       |
    | abc:haulage_worker  | abc:male        |
    | abc:haulage_worker  | abc:person      |
    | abc:male            | abc:adult       |
    | abc:male            | abc:male        |
    | abc:male            | abc:person      |
    | abc:man             | abc:adult       |
    | abc:man             | abc:male        |
    | abc:man             | abc:person      |
    | abc:person          | abc:adult       |
    | abc:person          | abc:male        |
    | abc:person          | abc:person      |
    | owl:Thing           | abc:adult       |
    | owl:Thing           | abc:male        |
    | owl:Thing           | abc:person      |
    -----------------------------------------

预期的输出将是这样的:

-----------------------------------------
    | class               | equivalentClass |
    =========================================
    | abc:adult           | abc:adult       |
    | abc:adult           | abc:male        |
    | abc:adult           | abc:person      |
    | abc:haulage_company |                 |
    | abc:haulage_company |                 |
    | abc:haulage_company |                 |
    | abc:haulage_worker  |                 |
    | abc:haulage_worker  |                 |
    | abc:haulage_worker  |                 |
    | abc:male            | abc:adult       |
    | abc:male            | abc:male        |
    | abc:male            | abc:person      |
    | abc:man             | abc:adult       |
    | abc:man             | abc:male        |
    | abc:man             | abc:person      |
    | abc:person          | abc:adult       |
    | abc:person          | abc:male        |
    | abc:person          | abc:person      |
    | owl:Thing           |                 |
    | owl:Thing           |                 |
    | owl:Thing           |                 |
    -----------------------------------------

我应该在SPARQL查询中更改什么才能使输出像上一个表一样?

1 个答案:

答案 0 :(得分:1)

稍微清理一下你的查询,我们有:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?equivalentClass where {
  ?class a owl:Class .
  filter( strstarts(str(?class),str(owl:)) ||     # since "owl:" is an IRI, you can 
          strstarts(str(?class),str(abc:))    )   # use str(owl:) and str(:abc)

  ?x a owl:Class ; 
     owl:intersectionOf ?list .
     ?list rdf:rest*/rdf:first ?equivalentClass .
}
group by ?class ?equivalentClass
order by ?class                                   # ?class, not ?no

您的问题在于您选择了?class,可以是本体中的每个owl:Class(只要以适当的前缀开头),然后选择?equivalentClass?x的交集类列表中,?x?class. (You were also sorting by没有任何联系?没有, but I think you meant to sort by?class`。)

如果我们以更易读的格式(例如Turtle)查看数据,那么找出要编写的查询会更容易。在Turtle中,man类是:

ns0:man  a                   owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( ns0:adult ns0:person ns0:male )
                             ] .

您正在查找owl:Class es,owl:equivalentClassowl:Class的其他内容相关的内容,以及owl:intersectionOf的列表值。这在SPARQL中并不太难,并且查询实际上具有与此Turtle文本相同的结构类型:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?otherClass where {
  ?class a owl:Class ;
         owl:equivalentClass [ a owl:Class ;
                               owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
  filter( strstarts(str(?class),str(owl:)) ||
          strstarts(str(?class),str(abc:))    )
}
group by ?class ?otherClass
order by ?class

我将变量名称从equivalentClass更改为otherClass,因为adultmaleperson不是等效man。他们的交集是。使用Jena的命令行sparql工具,您将获得如下结果:

$ sparql --data data.rdf --query query.rq
------------------------
| class   | otherClass |
========================
| abc:man | abc:adult  |
| abc:man | abc:male   |
| abc:man | abc:person |
------------------------

此查询仅检索与某个交集相同的类。您的预期结果显示所有IRI以abc:owl:开头的类,这意味着额外的结构实际上是可选的,因此我们通过将可选部分包装在optional { … }中来相应地调整查询,我们得到了我们正在寻找的那种结果:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?otherClass where {
  ?class a owl:Class .
  optional { 
    ?class owl:equivalentClass [ a owl:Class ;
                                 owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
  }
  filter( strstarts(str(?class),str(owl:)) ||
          strstarts(str(?class),str(abc:))    )
}
group by ?class ?otherClass
order by ?class
$ sparql --data data.rdf --query query.rq
------------------------------------
| class               | otherClass |
====================================
| abc:adult           |            |
| abc:haulage_company |            |
| abc:haulage_worker  |            |
| abc:male            |            |
| abc:man             | abc:adult  |
| abc:man             | abc:male   |
| abc:man             | abc:person |
| abc:person          |            |
| owl:Thing           |            |
------------------------------------