Используйте Jena для анализа перечисляемого типа данных, сгенерированного Protege

У меня есть файл онтологии, сгенерированный Protege 4.2.0. Он включает свойство DatatypeProperty, определенное следующим образом.

<owl:DatatypeProperty rdf:about="http://example.com/NLPSchema.owl#race">
    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
    <rdfs:domain rdf:resource="http://example.com/NLPSchema.owl#Person"/>
    <rdfs:subPropertyOf rdf:resource="http://example.com/NLPSchema.owl#semanticProperty"/>
    <rdfs:range>
        <rdfs:Datatype>
            <owl:oneOf>
                <rdf:Description>
                    <rdf:type rdf:resource="&rdf;List"/>
                    <rdf:first>african_american</rdf:first>
                    <rdf:rest>
                        <rdf:Description>
                            <rdf:type rdf:resource="&rdf;List"/>
                            <rdf:first>asian</rdf:first>
                            <rdf:rest>
                                <rdf:Description>
                                    <rdf:type rdf:resource="&rdf;List"/>
                                    <rdf:first>caucasian</rdf:first>
                                    <rdf:rest>
                                        <rdf:Description>
                                            <rdf:type rdf:resource="&rdf;List"/>
                                            <rdf:first>hispanic</rdf:first>
                                            <rdf:rest>
                                                <rdf:Description>
                                                    <rdf:type rdf:resource="&rdf;List"/>
                                                    <rdf:first>other</rdf:first>
                                                    <rdf:rest rdf:resource="&rdf;nil"/>
                                                </rdf:Description>
                                            </rdf:rest>
                                        </rdf:Description>
                                    </rdf:rest>
                                </rdf:Description>
                            </rdf:rest>
                        </rdf:Description>
                    </rdf:rest>
                </rdf:Description>
            </owl:oneOf>
        </rdfs:Datatype>
    </rdfs:range>
</owl:DatatypeProperty>

В Протеже это выглядит так:

Снимок экрана Protege

Теперь я использую Jena для разбора файла Ontology. Я могу получить объект OntClass, соответствующий тегу "диапазон":

DatatypeProperty p = ontModel.getDatatypeProperty("http://example.com/NLPSchema.owl#race");
OntClass range = p.getRange().asClass();    

Тогда как мне получить красивый нумерованный массив {"african_american", "asian", "caucasian", "латиноамериканец", "other"}, как в Protege?

Я знаю, что у DataRange есть метод под названием «listOneOf», однако я не знаю, как создать объект DataRange, по крайней мере, «p.isDataRange()» возвращает false.


person Yang Liu    schedule 22.02.2013    source источник
comment
Вы добились каких-либо успехов в этом?   -  person Joshua Taylor    schedule 22.04.2014


Ответы (2)


Рассмотрим эту небольшую онтологию, которая просто объявляет одно свойство DatatypeProperty, hasFlavor (сначала в RDF/XML, так как это то, что вы использовали):

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="http://example.org/icecream#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <owl:Ontology rdf:about="http://example.org/icecream"/>
  <owl:DatatypeProperty rdf:about="http://example.org/icecream#hasFlavor">
    <rdfs:range>
      <rdfs:Datatype>
        <owl:oneOf>
          <rdf:List>
            <rdf:first>chocolate</rdf:first>
            <rdf:rest>
              <rdf:List>
                <rdf:first>strawberry</rdf:first>
                <rdf:rest>
                  <rdf:List>
                    <rdf:first>vanilla</rdf:first>
                    <rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
                  </rdf:List>
                </rdf:rest>
              </rdf:List>
            </rdf:rest>
          </rdf:List>
        </owl:oneOf>
      </rdfs:Datatype>
    </rdfs:range>
  </owl:DatatypeProperty>
</rdf:RDF>

и снова, но на этот раз в Черепахе, так как ее легче читать:

@prefix :      <http://example.org/icecream#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

:hasFlavor  a       owl:DatatypeProperty ;
        rdfs:range  [ a          rdfs:Datatype ;
                      owl:oneOf  [ a          rdf:List ;
                                   rdf:first  "chocolate" ;
                                   rdf:rest   [ a          rdf:List ;
                                                rdf:first  "strawberry" ;
                                                rdf:rest   [ a          rdf:List ;
                                                             rdf:first  "vanilla" ;
                                                             rdf:rest   ()

                                                           ]
                                              ]
                                 ]
                    ] .

<http://example.org/icecream>
        a       owl:Ontology .

Важное свойство и его домен в Protégé:

имеет свойство Flavor в Protégé

Теперь все, что вам нужно сделать, это добраться до ресурса rdf:List, который является перечислением. hasFlavor имеет rdfs:range, который является owl:Datatype, а owl:Datatype связан с перечислением через owl:oneOf.

import java.util.List;

import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFList;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;

public class ExtractEnumeratedDatatypeElements {
    public static void main(String[] args) {
        // Load the ontology.
        final OntModel iceCream = ModelFactory.createOntologyModel( OntModelSpec.OWL_DL_MEM );
        iceCream.read( "file:///home/taylorj/tmp/ontologies/icecream/icecream.owl" );

        // Get to the property and the datatype that is its range.
        final DatatypeProperty hasFlavor = iceCream.createDatatypeProperty( "http://example.org/icecream#hasFlavor" );
        final Resource datatype = hasFlavor.getPropertyResourceValue( RDFS.range );

        // The datatype is related to a list of values by owl:oneOf.
        final RDFList enumeration = datatype.getPropertyResourceValue( OWL.oneOf ).as( RDFList.class );

        // The RDFList can be converted to a Java List.
        final List<RDFNode> list = enumeration.asJavaList();
        System.out.println( list );
    }
}

Это производит вывод:

[chocolate, strawberry, vanilla]
person Joshua Taylor    schedule 25.09.2013

Удалить

<rdf:type rdf:resource="&rdf;List"/>

это блокирует компактную запись в Turtle.

@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://example.com/NLPSchema.owl#race>
      a       owl:FunctionalProperty , owl:DatatypeProperty ;
      rdfs:domain <http://example.com/NLPSchema.owl#Person> ;
      rdfs:range
              [ a       rdfs:Datatype ;
                owl:oneOf ("african_american" "asian" "caucasian" "hispanic" "other")
              ] ;
      rdfs:subPropertyOf <http://example.com/NLPSchema.owl#semanticProperty> .
person AndyS    schedule 22.02.2013