【问题标题】:Retrieving all paths in an OWL class hierarchy with SPARQL and Jena使用 SPARQL 和 Jena 检索 OWL 类层次结构中的所有路径
【发布时间】:2013-07-19 15:53:43
【问题描述】:

我有一个层次结构深三层的 RDF 图。我想在不使用推理器的情况下检索从类层次结构的根(即owl:Thing)到第三级中的类的所有路径。例如,我想要路径 C1 → C2 → C3 是一条路径,其中每个 C 是层次结构的第 ith 级别的类。

我需要使用广度优先搜索算法检索 RDF 图中的所有路径,而不考虑图中的对象属性。

【问题讨论】:

  • 你把“东西”放在括号里。我对您的理解是否正确:您有一个带有一些根的类层次结构,并且您正在寻找从根到子类的所有路径(最大深度为 3)?您能否提供一个您希望返回的数据示例和结果?这将有助于制定解决方案。
  • 是的,我有一个类层次结构,但只有一个根,即事物是一个根类。
  • 以下面的本体为例:protege.cim3.net/file/pub/ontologies/camera/camera.owl 我想要的路径应该是 Thing - PurchaseableItem - Camera - Digital, Thing - PurchaseableItem -Camera - Large-Format 等等......和其他路径。谢谢。

标签: rdf semantic-web jena breadth-first-search


【解决方案1】:

给定一些这样的数据(其中类名的长度表示层次结构中类的深度):

@prefix : <http://example.org/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

:a a rdfs:Class .

:aa rdfs:subClassOf :a .
:ab rdfs:subClassOf :a .
:ac rdfs:subClassOf :a .

:aaa rdfs:subClassOf :aa .
:aab rdfs:subClassOf :aa .
:aac rdfs:subClassOf :aa .

:aaba rdfs:subClassOf :aab .
:aabb rdfs:subClassOf :aab .

:aba rdfs:subClassOf :ab .
:abb rdfs:subClassOf :ab .

您可以使用 SPARQL 查询来选择您要查找的路径。

使用 SPARQL 查询

您可以编写这样的 SPARQL 查询以获得以下结果:

prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?c1 ?c2 ?c3 where { 
  values ?c1 { :a }
  ?c1 ^rdfs:subClassOf ?c2 .
  OPTIONAL {
    ?c2 ^rdfs:subClassOf ?c3 .
  }
}
order by ?c3 ?c2 ?c1
-------------------
| c1 | c2  | c3   |
===================
| :a | :ac |      |
| :a | :aa | :aaa |
| :a | :aa | :aab |
| :a | :aa | :aac |
| :a | :ab | :aba |
| :a | :ab | :abb |
-------------------

使用相机本体

这种方法适用于 cmets 中提到的 camera ontology,尽管查询需要一些扩展来处理更深层次的类路径。因此:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX : <http://www.xfront.com/owl/ontologies/camera/#>

select * where { 
  values ?c1 { owl:Thing } 
  ?c1 ^rdfs:subClassOf ?c2 .
  OPTIONAL { 
    ?c2 ^rdfs:subClassOf ?c3 .
    OPTIONAL { 
      ?c3 ^rdfs:subClassOf ?c4 .
    }
  }
}
order by ?c4 ?c3 ?c2
-----------------------------------------------------------
| c1        | c2                | c3      | c4            |
===========================================================
| owl:Thing | :Money            |         |               |
| owl:Thing | :Range            |         |               |
| owl:Thing | :Window           |         |               |
| owl:Thing | :PurchaseableItem | :Body   |               |
| owl:Thing | :PurchaseableItem | :Lens   |               |
| owl:Thing | :PurchaseableItem | :Camera | :Digital      |
| owl:Thing | :PurchaseableItem | :Camera | :Large-Format |
-----------------------------------------------------------

使用耶拿 API

虽然上述 SPARQL 查询按照广度优先遍历所期望的顺序生成路径,但实际上并不能保证 ARQ 生成结果的方式。我们也可以直接实现广度优先搜索,使用 Jena 模型 API 来检索子类。这是一个简单的实现:

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;

public class BFSInRDFWithJena {

    public static List<List<Resource>> BFS( final Model model, final Queue<List<Resource>> queue, final int depth ) {
        final List<List<Resource>> results = new ArrayList<>();
        while ( !queue.isEmpty() ) {
            final List<Resource> path = queue.poll();
            results.add( path );
            if ( path.size() < depth ) {
                final Resource last = path.get( path.size() - 1 );
                final StmtIterator stmt = model.listStatements( null, RDFS.subClassOf, last );
                while ( stmt.hasNext() ) {
                    final List<Resource> extPath = new ArrayList<>( path );
                    extPath.add( stmt.next().getSubject().asResource() );
                    queue.offer( extPath );
                }
            }
        }
        return results;
    }

    public static void main( final String[] args ) throws IOException {
        final Model model = ModelFactory.createDefaultModel();
        try ( final InputStream in = BFSInRDFWithJena.class.getClassLoader().getResourceAsStream( "camera.owl" ) ) {
            model.read( in, null );
        }

        // setup the initial queue
        final Queue<List<Resource>> queue = new LinkedList<>();
        final List<Resource> thingPath = new ArrayList<>();
        thingPath.add( OWL.Thing );
        queue.offer( thingPath );

        // Get the paths, and display them
        final List<List<Resource>> paths = BFS( model, queue, 4 );
        for ( List<Resource> path : paths ) {
            System.out.println( path );
        }
    }
}
[http://www.w3.org/2002/07/owl#Thing]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Window]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Range]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Money]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Lens]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Body]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Digital]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Large-Format]

【讨论】:

  • 谢谢。但这不是我想要的。以以下本体为例:protege.cim3.net/file/pub/ontologies/camera/camera.owl我想要的路径应该看起来像 Thing PurchaseableItem Camera Digital 等等......
  • @user2502144 是的,所以您将:a 替换为owl:Thing,并且由于您似乎需要四层类(因为您包括owl:Thing),所以您再添加一层OPTIONAL 模式可以转到 ?c4
  • @user2502144 我已经更新了答案以显示如何将此查询与您链接到的camera.owl 一起使用。
  • Joshua 的答案是正确的,但这不是我需要检索这些路径的方法。我需要使用 Jena 中的广度优先搜索算法来检索 RDF 图中的所有路径。谢谢。
  • 好的,所以你的意思是你真的想使用 Jena Model 或 OntModel API 并编写遍历?看看another answer 我已经发布了关于使用 Jena 的 API 在 RDF 图上执行深度优先搜索的帖子。假设您已经熟悉如何实现广度优先和深度优先搜索,那么该示例应该显示了足够的 Jena 特定 API,您需要执行 BFS。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
相关资源
最近更新 更多