Apache Jena is a popular RDF library alongside RDF4J. According to one theory, Jena can do more, but learning is harder.
In fact, it's fairly easy to just make RDF normally, but I feel that the hurdle suddenly rises when trying to handle ontology such as OWL.
Apache Jena provides a consistent API for handling RDFS, OWL, etc. There seems to be few Japanese sources around here, so I'll leave a note here.
OWL is like a superset of RDFS (RDF Schema), which can roughly represent what RDFS can represent. For example, RDF properties can be represented hierarchically, but OWL properties can be extended to transitive, semantric, and functional. You can also describe reciprocal (reverse) relationships.
By the way, OWL includes OWL DL, which strictly distinguishes types based on description logic, and OWL Full, which has a practical ontology construction in mind. It also provides OWL Lite, a subset of OWL DL that is easier to implement.
The advantage of using an ontology is that you can use Reasoner to make inferences about your data. The Inference API allows Jena to take advantage of a variety of inference engines.
OntClass is the basic class, and various schemas (profiles) can be expressed in this class. This class is an extension of Jena's Model class and defines the constraints (construct) specified in the ontology. Specifically, it is generated via the Factory method as shown below.
OntModel m = ModelFactory.createOntologyModel();
In this case, it is generated with the default settings (OWL-Full, In-Memory, RDFS inference). Generally, the load is heavy, so you should use the appropriate settings. In that case, enter OntModelSpec as an argument. It looks like the following. The Language Profile (OWL Full, OWL DL, OWL Lite, RDFS) to be used is also set with this argument. There are 16 profiles. Specifically, please refer to API Document.
OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM);
In Jena's ontology model, when you try to handle multiple ontology, you will have a collection of models to import. Just like using Jana in general, use the read
method when importing an ontology.
read( String url )
read( Reader reader, String base )
read( InputStream reader, String base )
read( String url, String lang )
read( Reader reader, String base, String Lang )
read( InputStream reader, String base, String Lang )
When loading an ontology, it includes its own reference URI by default. Specifically, it is the URI specified by rdf: about
. In the sample of the official website, it is introduced as follows. The ontology referenced / loaded is shown by ʻowl: import. Is
dc` Dublin Core?
<owl:Ontology rdf:about="">
<dc:creator rdf:value="Ian Dickinson" />
<owl:imports rdf:resource="http://jena.apache.org/examples/example-ont" />
</owl:Ontology>
The ontology loaded in this way is kept as a separate graph structure. If more than one is loaded, it will be integrated as a Union Graph and referenced by Reasoner.
There are various options such as RDF persistence using these ontology. The following examples are introduced on the official website. ʻOntDocumentManager is a module that assists the processing of the ontology, and calls the ʻaddAltEntry
method there. It describes copying the ESWC ontology obtained by browsing the Internet to a local RDF for processing. It's hard to remember everything. .. ..
OntModel m = ModelFactory.createOntologyModel();
OntDocumentManager dm = m.getDocumentManager();
dm.addAltEntry( "http://www.eswc2006.org/technologies/ontology",
"file:" + JENA + "src/examples/resources/eswc-2006-09-21.rdf" );
m.read( "http://www.eswc2006.org/technologies/ontology" );
There seems to be banana-rdf natively implemented in scala in the world, but since the documentation is not complete, Jena is in scala. I would like to wrap it and use it.
This time, I will write the procedure in Ammonite-REPL.
//Download Jena
import $ivy.`org.apache.jena:jena-core:3.8.0`
import scala.collection.JavaConverters._
import org.apache.jena.rdf.model._
import org.apache.jena.ontology.OntModelSpec._
//Generate base model
val SOURCE = " http://rdfs.org/sioc/ns"
val NS = SOURCE + "#"
val base = ModelFactory.createOntologyModel(OWL_MEM)
base.read(SOURCE, "RDF/XML")
//Generate inference model by base model
val inf = ModelFactory.createOntologyModel(OWL_MEM_MICRO_RULE_INF, base)
val user = base.getOntClass(NS + "UserAccont")
val u1 = base.createIndividual(NS + "user1", user)
u1.listRDFTypes(true).toList.asScala.foreach{`type` => println( c1.getURI() + " is asserted in class " + `type`}
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
val inf_user = inf.getIndividual(NS + "user1")
inf_user.listRDFTypes(true).toList.asScala.foreach{`type` => println( inf_user.getURI() + " is asserted in class " + `type`}
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#User
First, pick up the ontology on the web and load it.
Next, refer to the ontology class for creating Individual (the part of getOntClass
) and generate it with createIndividual
.
The last part is inferred using the generated Individual URI. The logical value argument of listRDFTypes
indicates whether the class is directly referenced (Direct). In the output written in the comment part above, two classes are shown, but if you set the argument to false, you can get the following output. Somehow you can understand the meaning.
http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#User
http://rdfs.org/sioc/ns#account1 is asserted in class http://www.w3.org/2002/07/owl#Thing
http://rdfs.org/sioc/ns#account1 is asserted in class http://www.w3.org/2000/01/rdf-schema#Resource
http://rdfs.org/sioc/ns#account1 is asserted in class http://xmlns.com/foaf/0.1/OnlineAccount
There are many other things to remember, such as property descriptions and constraint condition descriptions. In any case, we can see that the Ontorogy API enables various inferences using the existing ontology.
That's all for today.