如何从耶拿的RDF中选择具有特定属性的主题?

时间:2013-09-17 07:44:25

标签: java rdf jena

这是我最后一个问题的后续问题,因为我仍在努力解决这个问题......我需要从我的模型中选择一些符合特定要求的主题。

如果我列出我的陈述(这只是输出的一小部分),我得到这样的东西:

WorkOrder2 hasType Workorder .
WorkOrder2 hasResult Fuselage22 .
WorkOrder2 type NamedIndividual .

现在,我想选择并迭代所有hasType Workorder的主题。我的想法是这样的:

public static ArrayList<String> listAllWorkorders(Model model) {
        ArrayList<String> workorders = new ArrayList<String>();

        // list of all work orders associated with given fuselage and work
        // station
        ResIterator it = model.listSubjectsWithProperty(
                ResourceFactory.createProperty(ArumCorePrefix + "hasType"), ArumCorePrefix + "Workorder");
        while (it.hasNext()) {
            Resource r = it.next();
            String workorder = trimPrefix(r.toString());

            workorders.add(workorder);

        }

        // sort the result alphabetically
        Collections.sort(workorders);

        return workorders;
    }

然而,它没有返回任何内容......如果我使用没有第二个参数(String)的listSubjectsWithProperty,它可以工作,但不仅返回工作器,而且返回一些具有hasType属性的toher东西,我不想要。我的代码出了什么问题!我可以使用这样的东西并使其工作吗? 不要担心static使用这个功能(一旦我认为错误,我会尽快处理这种非优雅的方式。)

另外,我想实现更多的compelx过滤 - 例如选择具有多个属性的主题,这些属性必须匹配才能返回它们,例如hasType Workorder, hasResult someResult, inStation station等...... Jena是否支持这样的事情!如果没有,常见的方法是什么?

感谢您的任何提示!

后续跟进:如何检查我的模型中是否存在某些陈述?我知道有model.contains(Statements s)方法,但我是否必须在roder中的参数中创建语句来调用此方法?是不是有一些更优雅的方式,如model.contains(Resource r, Property p, Resource o)

1 个答案:

答案 0 :(得分:1)

耶拿有多种方法可以做到这一点,但他们主要是打电话给

将资源作为第一个参数,将null作为第二个和第三个参数作为通配符。执行类似操作的其他方法实际上就是这种情况的特殊情况。例如,

  • listObjectsOfProperty(Property p) - listStatements(null,p,null)并从每个陈述中获取对象。
  • listObjectsOfProperty(Resource s, Property p) - listStatements(s,p,null)并从每个陈述中获取对象。
  • listResourcesWithProperty(Property p) - listStatements(null,p,null)并从每个声明中获取主题
  • listResourcesWithProperty(Property p, RDFNode o) - listStatements(null,p,o)并从每个声明中获取主题

为方便起见,您可能更喜欢使用方法

返回资源模型中所有语句的迭代器,并将给定资源作为主题。

以下是一些示例代码,其中包含您的模型并使用以下每种方法:

import java.io.ByteArrayInputStream;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.StmtIterator;

public class ResourcePropertiesExample {
    final static String NS = "http://example.org/";
    final static String modelText = "" +
            "@prefix : <"+NS+"> .\n" +
            ":WorkOrder2 :hasType :Workorder .\n" +
            ":WorkOrder2 :hasResult :Fuselage22 .\n" +
            ":WorkOrder2 :type :NamedIndividual .\n" +
            "";

    public static void main(String[] args) {
        final Model model = ModelFactory.createDefaultModel();
        model.read( new ByteArrayInputStream( modelText.getBytes()), null, "TTL" );
        final Resource workOrder2 = model.getResource( NS+"WorkOrder2" );

        System.out.println( "Using Model.listStatements()" );
        StmtIterator stmts = model.listStatements( workOrder2, null, (RDFNode) null );
        while ( stmts.hasNext() ) {
            System.out.println( stmts.next() );
        }

        System.out.println( "Using Resource.listProperties()" );
        stmts = workOrder2.listProperties();
        while ( stmts.hasNext() ) {
            System.out.println( stmts.next() );
        }
    }
}

输出结果为:

Using Model.listStatements()
[http://example.org/WorkOrder2, http://example.org/type, http://example.org/NamedIndividual]
[http://example.org/WorkOrder2, http://example.org/hasResult, http://example.org/Fuselage22]
[http://example.org/WorkOrder2, http://example.org/hasType, http://example.org/Workorder]
Using Resource.listProperties()
[http://example.org/WorkOrder2, http://example.org/type, http://example.org/NamedIndividual]
[http://example.org/WorkOrder2, http://example.org/hasResult, http://example.org/Fuselage22]
[http://example.org/WorkOrder2, http://example.org/hasType, http://example.org/Workorder]

至于检查模型是否包含某些语句,正如您所指出的,您可以使用Model.contains,我认为没有任何关系。您还可以使用各种资源has*方法,例如

  • hasLiteral(属性p,[各种类型的文字])
  • hasProperty(属性p,RDFNode / String / String,String)

使用这些,您可以使用,继续上面的示例,并假设您已定义属性hasResult和资源fuselage21fuselage22

workOrder2.hasProperty( hasResult, fuselage21 ); // false
workOrder2.hasProperty( hasResult, fuselage22 ); // true