Как добавить тройки RDF в OWLOntology?
У меня есть некоторые данные, поступающие с RabbitMQ. Данные форматируются как тройки, поэтому сообщение из очереди может выглядеть примерно так:
:Tom foaf:knows :Anna
где :
это стандартное пространство имен онтологии, в которое я хочу импортировать данные, но возможны и другие префиксы из импорта. Тройки состоят из субъекта, свойства / предиката и объекта, и я знаю, что в каждом сообщении есть что.
На принимающей стороне у меня есть Java-программа с OWLOntology
объект, представляющий онтологию, где вновь прибывшие тройки должны временно храниться для рассуждений и прочего. Я вроде сумел получить тройки в Йену OntModel
но на этом все и заканчивается. Я пытался использовать OWLRDFConsumer
но я не мог найти ничего о том, как его применить.
Моя функция выглядит примерно так:
public void addTriple(RDFTriple triple) {
//OntModel model = ModelFactory.createOntologyModel();
String subject = triple.getSubject().toString();
subject = subject.substring(1,subject.length()-1);
Resource s = ResourceFactory.createResource(subject);
String predicate = triple.getPredicate().toString();
predicate = predicate.substring(1,predicate.length()-1);
Property p = ResourceFactory.createProperty(predicate);
String object = triple.getObject().toString();
object = object.substring(1,object.length()-1);
RDFNode o = ResourceFactory.createResource(object);
Statement statement = ResourceFactory.createStatement(s, p, o);
//model.add(statement);
System.out.println(statement.toString());
}
Я выполнил операции с подстрокой, потому что класс RDFTriple добавляет <> к аргументам тройки и, как следствие, конструктор Statement завершается неудачей.
Если бы кто-нибудь мог указать мне пример, который был бы великолепен. Может быть, есть намного лучший способ, которым я не думал достичь того же самого?
2 ответа
Похоже, что OWLRDFConsumer обычно используется для соединения анализаторов RDF с процессорами, поддерживающими OWL. Следующий код, кажется, работает, хотя, как я заметил в комментариях, есть пара мест, где я нуждался в аргументе и вставлял единственную доступную вещь, которую мог.
Следующий код: создает онтологию; объявляет двух названных людей, Тома и Анны; объявляет свойство объекта, лайки; и объявляет свойство данных, возраст. Как только они объявлены, мы печатаем онтологию просто для того, чтобы убедиться, что это то, что мы ожидаем. Затем он создает OWLRDFConsumer. Потребительский конструктор нуждается в онтологии, AnonymousNodeChecker и OWLOntologyLoaderConfiguration. Для конфигурации я просто использовал созданный конструктором без аргументов, и я думаю, что все в порядке. Для проверки узлов единственным удобным средством реализации является TurtleParser, поэтому я создал один из них, передав null
как читатель Я думаю, что все будет в порядке, так как парсер не будет вызываться для чтения чего-либо. Затем методы обработчика (IRI,IRI,IRI) и обработчика (IRI,IRI,OWLLiteral) используются для обработки триплетов по одному за раз. Добавляем тройки
:Tom :likes :Anna
:Tom :age 35
а затем снова распечатайте онтологию, чтобы убедиться, что утверждения были добавлены. Поскольку вы уже получаете RDFTriples, вы должны быть в состоянии извлечь аргументы, необходимые для handle(). Перед обработкой троек онтология содержала:
<NamedIndividual rdf:about="http://example.org/Tom"/>
и после этого:
<NamedIndividual rdf:about="http://example.org/Tom">
<example:age rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">35</example:age>
<example:likes rdf:resource="http://example.org/Anna"/>
</NamedIndividual>
Вот код:
import java.io.Reader;
import org.coode.owlapi.rdfxml.parser.OWLRDFConsumer;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyLoaderConfiguration;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import uk.ac.manchester.cs.owl.owlapi.turtle.parser.TurtleParser;
public class ExampleOWLRDFConsumer {
public static void main(String[] args) throws OWLOntologyCreationException, OWLOntologyStorageException {
// Create an ontology.
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
OWLDataFactory factory = manager.getOWLDataFactory();
OWLOntology ontology = manager.createOntology();
// Create some named individuals and an object property.
String ns = "http://example.org/";
OWLNamedIndividual tom = factory.getOWLNamedIndividual( IRI.create( ns+"Tom" ));
OWLObjectProperty likes = factory.getOWLObjectProperty( IRI.create( ns+"likes" ));
OWLDataProperty age = factory.getOWLDataProperty( IRI.create( ns+"age" ));
OWLNamedIndividual anna = factory.getOWLNamedIndividual( IRI.create( ns+"Anna" ));
// Add the declarations axioms to the ontology so that the triples involving
// these are understood (otherwise the triples will be ignored).
for ( OWLEntity entity : new OWLEntity[] { tom, likes, age, anna } ) {
manager.addAxiom( ontology, factory.getOWLDeclarationAxiom( entity ));
}
// Print the the ontology to see that the entities are declared.
// The important result is
// <NamedIndividual rdf:about="http://example.org/Tom"/>
// with no properties
manager.saveOntology( ontology, System.out );
// Create an OWLRDFConsumer for the ontology. TurtleParser implements AnonymousNodeChecker, so
// it was a candidate for use here (but I make no guarantees about whether it's appropriate to
// do this). Since it won't be reading anything, we pass it a null InputStream, and this doesn't
// *seem* to cause any problem. Hopefully the default OWLOntologyLoaderConfiguration is OK, too.
OWLRDFConsumer consumer = new OWLRDFConsumer( ontology, new TurtleParser((Reader) null), new OWLOntologyLoaderConfiguration() );
// The consumer handles (IRI,IRI,IRI) and (IRI,IRI,OWLLiteral) triples.
consumer.handle( tom.getIRI(), likes.getIRI(), anna.getIRI() );
consumer.handle( tom.getIRI(), age.getIRI(), factory.getOWLLiteral( 35 ));
// Print the ontology to see the new object and data property assertions. The import contents is
// still Tom:
// <NamedIndividual rdf:about="http://example.org/Tom">
// <example:age rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">35</example:age>
// <example:likes rdf:resource="http://example.org/Anna"/>
// </NamedIndividual>
manager.saveOntology( ontology, System.out );
}
}
В ONT-API (который также является OWL-API) это очень просто:
OWLOntologyManager manager = OntManagers.createONT();
OWLOntology ontology = manager.createOntology(IRI.create("http://example.com#test"));
((OntologyModel)ontology).asGraphModel().createResource("http://example.com#clazz1").addProperty(RDF.type, OWL.Class);
ontology.axioms(AxiomType.DECLARATION).forEach(System.out::println);
Это путь Джена здесь. Для получения дополнительной информации см. Вики-интерфейс ONT-API.