I have an OWL ontology file as RDF and want to store my data in a TDB and want to use reasoning. Actually this sounds simple so far :)
But here is the point where I'm confuesd:
I created a TDB an stored via SPARQL some statements. Then I tried to load the TDB via a model and OWL reasoner:
OntModelSpec ontModelSpec = OntModelSpec.OWL_MEM;
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
ontModelSpec.setReasoner(reasoner);
Model schemaModel = FileManager.get().loadModel("D:/Users/jim/Desktop/ontology/schema.rdf");
OntModel schema = ModelFactory.createOntologyModel( ontModelSpec, schemaModel);
Location location = new Location("D:/Users/jim/Desktop/jena-fuseki-0.2.5/DB");
Dataset dataset = TDBFactory.createDataset(location);
Model model = dataset.getDefaultModel();
OntModel ontModel = ModelFactory.createOntologyModel(ontModelSpec, model);
When I now create new resources via API, they are not stored in the TDB. And I'm not able to see the Statments have added via SPARQL?!
The SPAQRL statement shows me only the entries I've added with SPARQL
QueryExecution qExec = QueryExecutionFactory.create(
StrUtils.strjoinNL("SELECT ?s ?p ?prop",
"WHERE {?s ?p ?prop}"),
dataset) ;
ResultSet rs = qExec.execSelect() ;
try {
ResultSetFormatter.out(rs) ;
} finally { qExec.close() ; System.out.println("closed connection");}
and this returns only the Resource added with the API
System.out.print("instance: " + ontModel.getResource(NS + "TestItem"));
And when I call this:
ExtendedIterator<Statement> iter = ontModel.listStatements();
I get the following exception:
org.openjena.atlas.lib.InternalErrorException: Invalid id node for subject (null node): ([0000000000000067], [0000000000000093], [00000000000000C8])
Is someone able to explain that behavior? Or could someone please give me a hint how to separate schema and date with TDB in right way with using the OntModel?
Partial answer:
org.openjena.atlas.lib.InternalErrorException: Invalid id node for subject (null node): ([0000000000000067], [0000000000000093], [00000000000000C8])
You are using TDB without transactions - try adding TDB.sync before exiting to flush changes to the disk.
Related
I've been following the ARQ guide on Property Functions. The section on Graph Operations concludes with "New Triples or Graphs can therefore be created as part of the Property Function" and I've been hoping to use this as a means to add triples to the current query execution context (and not to persist), accessible for the remaining query.
I've been trying the code snippets in that section of the guide:
DatasetGraph datasetGraph = execCxt.getDataset();
Node otherGraphNode = NodeFactory.createURI("http://example.org/otherGraph");
Graph newGraph = new SimpleGraphMaker().createGraph();
Triple triple = ...
newGraph.add(triple);
datasetGraph.addGraph(otherGraphNode, newGraph);
but I'm running into issues, seemingly with the read-lock.
org.apache.jena.dboe.transaction.txn.TransactionException: Can't become a write transaction
at org.apache.jena.dboe.transaction.txn.Transaction.ensureWriteTxn(Transaction.java:251) ~[fuseki-server.jar:4.2.0]
at org.apache.jena.tdb2.store.StorageTDB.ensureWriteTxn(StorageTDB.java:200) ~[fuseki-server.jar:4.2.0]
at org.apache.jena.tdb2.store.StorageTDB.add(StorageTDB.java:81) ~[fuseki-server.jar:4.2.0]
at org.apache.jena.dboe.storage.system.DatasetGraphStorage.add(DatasetGraphStorage.java:181) ~[fuseki-server.jar:4.2.0]
at org.apache.jena.dboe.storage.system.DatasetGraphStorage.lambda$addGraph$1(DatasetGraphStorage.java:194) ~[fuseki-server.jar:4.2.0]
Is there any way to add triples to the execution context during a SPARQL query?
Yes, and SPARQL Anything uses that capability to triplify non-RDF data at query time and makes it available in the execution context's DatasetGraph.
Here is an example of that being done:
if (this.execCxt.getDataset().isEmpty()) {
// we only need to call getDatasetGraph() if we have an empty one
// otherwise we could triplify the same data multiple times
dg = getDatasetGraph(p, opBGP);
} else {
dg = this.execCxt.getDataset();
}
These lines
This answer might not address your particular need (adding individual triples) but hopefully some of code in the project could serve as an example of what you are looking for.
executing the following code:
Query query = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(query, model);
Model m = qexec.execConstruct(model);
System.out.println(m.toString());
model.close();
sometimes arises the java.util.ConcurrentModificationException exeception, depending on the type of query I'm executing. There is a way to build an always-safe snippet of code? Thank you.
Use Model m = qexec.execConstruct() (no model argument) then call model.add(m).
If you query and insert statements on the same model, via execConstruct(model)) there is a risk of CCME. Using a different model for the results avoids that.
I generally keep my ontologies in two different files.
First ontology file contains the classes, subclasses, data properties and object properties.
The second file containing all the individuals and relationships between the individuals.
So, I need to merge these two files in order to have a complete model. I wonder how this could be achieved using owlapi?
In Jena, I do this as follows:
OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
null);
try {
model.read(new FileInputStream(MyOntologyFile), "...");
model.read(new FileInputStream(MyOntologyWithIndividualsFile), "...");
} catch (Exception e) {
log.error("Loading Model failed:" + e);
}
In the similar fashion when I tried to load my ontology files using owlapi, I get error:
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
OWLObjectRenderer renderer = new DLSyntaxObjectRenderer();
File file = new File(MyOntologyFile);
File fileIndividuals = new File(MyOntologyWithIndividualsFile);
OWLOntology localOntology = null;
// Now load the local copy
try {
localOntology = manager.loadOntologyFromOntologyDocument(file);
localOntology = manager
.loadOntologyFromOntologyDocument(fileIndividuals);
} catch (OWLOntologyCreationException ex) {
ex.printStackTrace();
}
Error:
org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException: Ontology already exists. OntologyID(OntologyIRI(<http://www.semanticweb.org/lp4220/ontologies/2014/4/untitled-ontology-35>))
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntology(OWLOntologyManagerImpl.java:880)
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFromOntologyDocument(OWLOntologyManagerImpl.java:806)
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFromOntologyDocument(OWLOntologyManagerImpl.java:821)
Update:
As it turns out, merging of ontologies is only possible with those having different IRI's, and hence I presume it is not acceptable to divide an ontology into two with the same IRI. A solution for this (as commented by Joshua) may be to read all individuals and axioms from one ontology and then add them to an already loaded ontology.
For ontologies with distinct IRI's merging can be done as follows (example courtesy Ignazio's OWLED 2011 slides - slide no. 27):
OWLOntologyManager m = create();
OWLOntology o1 = m.loadOntology(pizza_iri);
OWLOntology o2 = m.loadOntology(example_iri);
// Create our ontology merger
OWLOntologyMerger merger = new OWLOntologyMerger(m);
// Merge all of the loaded ontologies, specifying an IRI for the
new ontology
IRI mergedOntologyIRI =
IRI.create(
"http://www.semanticweb.com/mymergedont"
);
OWLOntology merged = merger.createMergedOntology(m,
mergedOntologyIRI);
assertTrue(merged.getAxiomCount() > o1.getAxiomCount());
assertTrue(merged.getAxiomCount() > o2.getAxiomCount());
Your problem is not having the same iri in the data but ontologies with the same iris loaded in the same manager. Load the ontologies in separate managers and add all the axioms from one to the other, that will give you a merged ontology.
In general, you do not make "Individuals and Relationships" an Ontology, unless they require for classifications - say to define Class "American Company" you need an Individual "US". Otherwise, that other part is should be your RDF triples that refer to the Ontology.
I am currently writing some code in Java, using Jena and TDB -- on a Windows 7.
I want to be able to load a (large) .trig file into TDB Dataset so that querying is a bit faster. The code that I currently have is:
Dataset dataset = TDBFactory.createDataset(directoryPath);
Model tdb = dataset.getDefaultModel();
RDFDataMgr.read(tdb, inputFilePath);
try {
String theQuery = readFile(testQueryPath, Charset.defaultCharset());
Query query = QueryFactory.create(theQuery);
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
com.hp.hpl.jena.query.ResultSet results = qe.execSelect();
// Output query results
ResultSetFormatter.out(System.out, results, query);
qe.close();
} catch (IOException e) {
e.printStackTrace();
}
I also tried:
FileManager.get().readModel( tdb, inputFilePath);
instead of:
RDFDataMgr.read(tdb, inputFilePath);
I get the following warning:
2014-06-13 13:02:26 WARN riot:77 - Only triples or default graph data expected : named graph data ignored
The SPARQL queries I ran are:
PREFIX xsd: http://www.w3.org/2001/XMLSchema#
PREFIX dc: http://purl.org/dc/elements/1.1/
PREFIX : <.>
SELECT *
{
{ ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } }
}
and also the same one but without the UNION and GRAPH things.
The queries return nothing.
Does anyone see an apparent problem or know how to load .trig files into TDB?
You just read into the dataset:
RDFDataMgr.read(dataset, inputFilePath);
Inside write transaction would be better else call TDB.sync(dataset) before you exit.
You code loads it every run. If the file is really big, use tdbloader, the bulk loader, before running the query program.
Basically, I use the Any23 distiller to extract RDF statements from files embedded with RDFa (The actual files where created by DBpedia Spotlight using the xhtml+xml output option). By using Any23 RDFa distiller I can extract the RDF statements (I also tried using Java-RDFa but I could only extract the prefixes!). However, when I try to pass the statements to a Jena model and print the results to the console, nothing happens!
This is the code I am using :
File myFile = new File("T1");
Any23 runner= new Any23();
DocumentSource source = new FileDocumentSource(myFile);
ByteArrayOutputStream outA = new ByteArrayOutputStream();
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()); //convert the output stream to input so i can pass it to jena model
TripleHandler writer = new NTriplesWriter(outA);
try {
runner.extract(source, writer);
} finally {
writer.close();
}
String ttl = outA.toString("UTF-8");
System.out.println(ttl);
System.out.println();
System.out.println();
Model model = ModelFactory.createDefaultModel();
model.read(decodedInput, null, "N-TRIPLE");
model.write(System.out, "TURTLE"); // prints nothing!
Can anyone tell me what I have done wrong? Probably multiple things!
Is there any easy way i can extract the subjects of the RDF statements directly from any23 (bypassing Jena)?
As I am quite inexperienced in programming any help would be really appreciated!
You are calling
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()) ;
before calling any23 to insert triples. At the point of the call, it's empty.
Move this after the try-catch block.