Search code examples
jenauser-defined-data-types

How to create user defined datatypes in Apache Jena?


I'm creating an ontology using Apache Jena. However, I can't find a way of creating custom datatypes as in the following example: 'has value' some xsd:float[>= 0.0f , <= 15.0f].

Do you have any ideas?


Solution

  • It seems what you need is DatatypeRestriction with two facet restrictions: xsd:minInclusive and xsd:maxInclusive. It is OWL2 constructions.

    org.apache.jena.ontology.OntModel does not support OWL2, only OWL1.1 partially (see documentation), and, therefore, there are no builtin methods for creating such data-ranges (there is only DataOneOf data range expression, see OntModel#createDataRange(RDFList)).

    So you have to create a desired datatype manually, triple by triple, using the general org.apache.jena.rdf.model.Model interface. In RDF, it would look like this:

    _:x rdf:type rdfs:Datatype.
    _:x owl:onDatatype DN.
    _:x owl:withRestrictions (_:x1 ... _:xn).
    

    See also owl2-quick-guide.

    Or, to build such an ontology, you can use some external utilities or APIs. For example, in ONT-API (v. 2.x.x) the following snippet

        String ns = "https://stackoverflow.com/questions/54131709#";
        OntModel m = OntModelFactory.createModel()
                .setNsPrefixes(OntModelFactory.STANDARD).setNsPrefix("q", ns);
        OntDataRange.Named floatDT = m.getDatatype(XSD.xfloat);
        OntFacetRestriction min = m.createFacetRestriction(OntFacetRestriction.MinInclusive.class,
                floatDT.createLiteral("0.0"));
        OntFacetRestriction max = m.createFacetRestriction(OntFacetRestriction.MaxInclusive.class,
                floatDT.createLiteral("15.0"));
        OntDataRange.Named myDT = m.createDatatype(ns + "MyDatatype");
        myDT.addEquivalentClass(m.createDataRestriction(floatDT, min, max));
        m.createResource().addProperty(m.createDataProperty(ns + "someProperty"),
                myDT.createLiteral("2.2"));
        m.write(System.out, "ttl");
    

    will produce the following ontology:

    @prefix q:     <https://stackoverflow.com/questions/54131709#> .
    @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix owl:   <http://www.w3.org/2002/07/owl#> .
    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
    
    [ q:someProperty  "2.2"^^q:MyDatatype ] .
    
    q:MyDatatype  a              rdfs:Datatype ;
            owl:equivalentClass  [ a                     rdfs:Datatype ;
                                   owl:onDatatype        xsd:float ;
                                   owl:withRestrictions  ( [ xsd:minInclusive  "0.0"^^xsd:float ]
                                                           [ xsd:maxInclusive  "15.0"^^xsd:float ]
                                                         )
                                 ] .
    
    q:someProperty  a  owl:DatatypeProperty .