1

我有一个可以使用的 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;
    }

但我很确定这是非常无效的方法..你能建议我一些更优雅和快速的方法吗?谢谢!

4

1 回答 1

3

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

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

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

现在,为了处理资源之间的关系,正如将主体资源连接到对象的属性的 URI 所给出的那样,您需要谓词的完整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 词汇生成器工具。您可以使用 schemagen 作为构建过程的一部分,以确保您的词汇类在您的本体更改时自动保持最新。

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

于 2013-09-16T14:23:14.617 回答