【问题标题】:Jena - how to use ontology + rdf togetherJena - 如何一起使用本体 + rdf
【发布时间】:2013-09-16 11:28:12
【问题描述】:

我有一个可以使用的 RDF 文件

Model model = ModelFactory.createDefaultModel();

// use the FileManager to find the input file
InputStream in = FileManager.get().open(args[0]);
if (in == null) {
    throw new IllegalArgumentException(
     "File: " + args[0] + " not found");
}

// read the RDF/XML file
model.read(in, null);

我还有一个 OWL 文件,其中包含用于创建我的模型的本体描述。我的问题是:我是否需要阅读此文件(以及如何阅读?)才能正确使用我的 RDF 模型?

为了说明清楚,我举个例子: 我需要知道一个资源是否与其他资源有某种关系(例如Station1 has predicate "isResponsibleFor" Workorder1)。我怎样才能用 Jena 做到这一点?

如果我尝试使用 resource.hasProperty(ResourceFactory.createProperty("isResponsibleFor")) 之类的东西,它会返回 false(但属性在那里!)。

您能否指导我阅读有关此主题的一些高级教程?我在 Papache 网站等上找到了许多教程,但它们没有为我提供我正在寻找的信息。对不起,如果问题不清楚,我对耶拿很陌生

编辑:目前,我正在搜索我的模型是否包含给定的语句:

public static boolean containsStatement(Model model, String sub,
            String pred, String obj) {
        // list the statements in the Model
        StmtIterator iter = model.listStatements();

        // print out the predicate, subject and object of each statement
        while (iter.hasNext()) {
            Statement stmt = iter.nextStatement(); // get next statement
            Resource subject = stmt.getSubject(); // get the subject
            Property predicate = stmt.getPredicate(); // get the predicate
            RDFNode object = stmt.getObject(); // get the object

            if (subject.toString().contains(sub)
                    && predicate.toString().contains(pred)
                    && object.toString().contains(obj)) {
                return true;
            }
        }

        return false;
    }

但我很确定这是一种非常无效的方法。你能给我推荐一些更优雅、更快速的方法吗?谢谢!

【问题讨论】:

    标签: java rdf jena ontology


    【解决方案1】:

    简短回答:不,您不需要本体来处理您的 RDF 文件,但在许多情况下它可以帮助您的应用程序。

    首先,您可以缩短文件的加载时间:

    Model model = FileManager.get().loadModel( args[0] );
    

    现在,为了处理资源之间的关系,由连接主体资源和对象的属性的 URI 给出,您需要谓词的 full URI。通常,这将类似于http://example.com/foo#isResponsibleFor。如果您只使用谓词的短名称,它将不起作用 - 这就是您所发现的。

    您没有显示任何实际 RDF 数据的示例,因此我将使用假命名空间。在代码中使用您的实际命名空间。同时:

    String NS = "http://example.com/example#";
    Property isResponsibleFor = model.getProperty( NS + "isResponsibleFor" );
    
    Resource station = model.getResource( NS + "station1" );
    
    for (StmtIterator i = station.listProperties( isResponsibleFor ); i.hasNext(); ) {
      Statement s = i.next();
      Resource workorder = s.getResource();
      // now you can do something with the work-order resource
    }
    

    在您的代码中,您有:

    public static boolean containsStatement(Model model, String sub, String pred, String obj)
    

    这里有很多问题。首先,如果您可以以更面向对象的风格编写代码会更好,如果可以避免这种情况,则倾向于不使用static 方法。其次,在引用模型中的事物时不要使用字符串。 Jena 有Resource 类来表示模型中的资源,还有许多其他特定于RDF 的类。使用字符串处理来自用户的输入,否则尽快将字符串转换为资源或其他 RDF 对象。第三,我建议不要通过对象的 API 公开表示的详细信息。 containsStatement 在 API 中明确表明您正在使用 RDF 三元组;这不是 API 调用者需要知道的细节,它破坏了封装。更好的 API 将具有诸如 listWorkItems 之类的方法,这些方法与域相关,并隐藏了实现的细节。

    关于本体的使用,您的应用程序可以通过两种特定方式从使用本体中受益。首先,可以自动生成语句如:

    Property isResponsibleFor = model.getProperty( NS + "isResponsibleFor" );
    

    使用 Jena 的 schemagen vocabulary generator tool。您可以将 schemagen 用作构建过程的一部分,以确保您的词汇类在您的本体发生变化时自动保持最新。

    其次,通过使用 Jena 的 inference engines,您可以使用本体推断有关您的域的其他陈述。例如,假设您有类WidgetOrder,它是WorkItem 的一种类型。没有推理,也没有你的本体,如果你要求模型对象列出所有WorkItems,它不会列出WidgetOrder 资源。但是,通过本体和推理器,列出WorkItem 类型的资源也将返回仅声明类型为WidgetOrder 的资源,因为可以推断出其他类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多