2013-09-17 2 views
1

Это последний вопрос по моему последнему, так как я до сих пор борюсь с этой темой ... Мне нужно выбрать некоторые темы из моей модели, соответствующие конкретным требованиям.Как выбрать объекты с определенными свойствами из RDF с Jena?

Если я перечислю свои заявления (это только короткая часть продукции), я получаю что-то вроде этого:

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

Теперь я хотел бы, чтобы выбрать и перебирать thourgh всех предметов, которые 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; 
    } 

Однако, он не возвращает ничего ... Если я использую listSubjectsWithProperty без второго аргумента (String), он работает, но возвращает не только Workorders, но некоторые вещи toher с hasType собственности , чего я не хочу. Что не так с моим кодом! Могу ли я использовать что-то вроде этого и заставить его работать? Dont беспокоиться о static использования этой функции (я буду заботиться о этом, не изящным способом, как только я udnerstand, что случилось.)

Кроме того, я хотел бы реализовать некоторые более compelx фильтрации - например выбор предметов с несколькими свойствами, которые все должны соответствовать, чтобы их вернуть, например hasType Workorder, hasResult someResult, inStation station и т. д. Поддерживает ли Jena что-то вроде этого! Если нет, то какой общий подход?

Спасибо за любые советы!

И последующее: Как проверить, присутствует ли какое-либо утверждение в моей модели? Я знаю, что существует метод model.contains(Statements s), но мне нужно создать оператор в аргументе в roder для вызова этого метода? Разве нет более элегантного способа, как model.contains(Resource r, Property p, Resource o)?

ответ

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) и взять предмет из каждого оператора

Для удобства, вы можете предпочесть использовать метод

которые возвращаются s итератор по всем операторам модели ресурса с данным ресурсом как предмет.

Вот пример кода, который включает в себя модель и использует каждый из этих методов:

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 (Свойство р, [различные типы буквальным])
  • HasProperty (Свойство р, RDFNode/String/String, String)

с их помощью можно использовать, продолжая пример выше, и предполагая, что вы бы определили свойство hasResult и ресурсы fuselage21 и fuselage22:

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

Спасибо за ваш ответ, но у меня все еще есть проблема: когда я вызываю model.contains (wororder, hasResult, NS + "fuselage22") ;, он говорит false, и я не знаю, почему .. resource.has (свойство p) тоже не работает, даже несмотря на то, что сателлиты там нет ... – Smajl

+0

Существует разница между 'NS + 'fuselage22" ', которая является строкой, и' model.getResource (NS + "fuselage22") ', которая создает ресурс. Операторы, которые содержат модель (в данном случае), имеют _resources_ как свои объекты, а не строки. Вот почему я сделал, например, «окончательный ресурс workOrder2 = model.getResource (NS +« WorkOrder2 »);'. Вам нужно сделать «final Resource fuselage22 = model.getResource (NS +« fuselage22 »);'. –