java - 如何更新 OWL 本体文件以添加具有某些属性的新个体?

标签 java rdf owl protege owl-api

我在 protege 4.3.0 中创建了一个本体并存储在 OWL 文件中。我需要向该本体添加一些个体并更新该文件。由于这些个体彼此非常相似,我想利用 OWL API 来比手动使用程序更快地添加它们。

我的目标如下:

  • 添加新的个体#individualSimpleSubType
  • 将类型 #SimpleSubType 添加到此个体(#SimpleSubType#SimpleType 的子类)
  • 将以下对象属性断言添加到此个体:与 #PropertyValue1 关联的 #hasProperty1
  • 将以下对象属性断言添加到此个体:与 #PropertyValue2 关联的 #hasProperty2

以下信息已存在于本体中:

  • #SimpleType及其子类#SimpleSubType
  • 对象属性#hasProperty1#hasProperty2
  • 个人#PropertyValue1#PropertyValue2

以下是我用来尝试实现该目标的代码:

OWLOntologyManager manager = OWLManager.createOWLOntologyManager();

try {
    OWLOntology ontology = manager.loadOntologyFromOntologyDocument(new File("ontology.owl"));

    IRI ontologyIRI = ontology.getOntologyID().getOntologyIRI();
    PrefixManager prefixManager = new DefaultPrefixManager(ontologyIRI.toString().concat("#"));

    OWLDataFactory dataFactory = manager.getOWLDataFactory();

    OWLReasonerFactory reasonerFactory = new StructuralReasonerFactory();
    OWLReasoner reasoner = reasonerFactory.createReasoner(ontology);
    reasoner.precomputeInferences();

    // Get all subclasses of SimpleType stored within the loaded ontology.
    OWLClassNodeSet clsSimpleSubTypes = new OWLClassNodeSet();
    OWLClass simpleTypeClass = dataFactory.getOWLClass(":SimpleType", prefixManager);
    clsSimpleSubTypes.addDifferentEntities(reasoner.getSubClasses(simpleTypeClass, true).getFlattened());

    // Get two object properties stored within the loaded ontology.
    OWLObjectPropertyExpression objProperty1 = dataFactory.getOWLObjectProperty(IRI.create(ontologyIRI + "#hasProperty1"));
    OWLObjectPropertyExpression objProperty2 = dataFactory.getOWLObjectProperty(IRI.create(ontologyIRI + "#hasProperty2"));

    // Get two property values stored within the loaded ontology.
    OWLNamedIndividual propertyValue1 = dataFactory.getOWLNamedIndividual(IRI.create(ontologyIRI + "#PropertyValue1"));
    OWLNamedIndividual propertyValue2 = dataFactory.getOWLNamedIndividual(IRI.create(ontologyIRI + "#PropertyValue2"));

    for (OWLClass cls : clsSimpleSubTypes.getFlattened())
    {
        if (cls.getIRI().toString().endsWith("#SimpleSubType")) {
            // Create the new individual
            OWLNamedIndividual po = factory.getOWLNamedIndividual(IRI.create(ontologyIRI + "#individualSimpleSubType"));

            // individualSimpleSubType is of type SimpleSubType
            OWLClassAssertionAxiom assertion = dataFactory.getOWLClassAssertionAxiom(cls, po);
            manager.addAxiom(ontology, assertion);

            // individualSimpleSubType has object property PropertyValue1
            OWLObjectPropertyAssertionAxiom objProperty1Axiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objProperty1, po, propertyValue1);
            manager.addAxiom(ontology, objProperty1Axiom);

            // individualSimpleSubType has object property PropertyValue2
            OWLObjectPropertyAssertionAxiom objProperty2Axiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objProperty2, po, propertyValue2);
            manager.addAxiom(ontology, objProperty2Axiom);

            break;
        }
    }

    //File destinationFile = new File("ontology-new-data.owl");
    //OWLOntologyFormat format = manager.getOntologyFormat(ontology);
    //manager.saveOntology(ontology, format, IRI.create(destinationFile.toURI()));
    manager.saveOntology(ontology);
} catch (OWLOntologyCreationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (OWLOntologyStorageException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

但是,使用上面的代码,我得到的结果与使用 Protegé 得到的结果不同。

如果我按照上面的说明使用 Protegé 添加新个体,则 OWL 文件将更新并添加以下 XML 行:

<!-- http://www.semanticweb.org/vincenzo/ontologies/2015/7/ontology.owl#individualSimpleSubType -->

<owl:NamedIndividual rdf:about="http://www.semanticweb.org/vincenzo/ontologies/2015/7/ontology.owl#individualSimpleSubType">
    <rdf:type rdf:resource="http://www.semanticweb.org/vincenzo/ontologies/2015/7/ontology.owl#SimpleSubType"/>
    <hasProperty1 rdf:resource="http://www.semanticweb.org/vincenzo/ontologies/2015/7/ontology.owl#PropertyValue1"/>
    <hasProperty2 rdf:resource="http://www.semanticweb.org/vincenzo/ontologies/2015/7/ontology.owl#PropertyValue2"/>
</owl:NamedIndividual>

但是,如果我使用上面的Java代码,保存本体还涉及到其他行的修改:将与上面相同的XML行添加到文件中,但也修改了其他行,如下。

上面的Java代码保存的OWL文件的开头写入了以下几行(但是当我在执行相同的修改后使用Protégé保存本体时,不会写入这些行)。

<!DOCTYPE rdf:RDF [
    <!ENTITY terms "http://purl.org/dc/terms/" >
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY skos "http://www.w3.org/2004/02/skos/core#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>

然后,在一些标签的属性中添加一定的前缀,所以:

  1. 原始 OWL 文件的属性 rdf:resource="&rdf;List" 替换为 rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
  2. 原始 OWL 文件的属性 rdf:resource="&owl;TransitiveProperty" 替换为 rdf:resource="http://www.w3.org/2002/07/owl#TransitiveProperty"
  3. 原始 OWL 文件的属性 rdf:about="&terms;description" 替换为 rdf:about="http://purl.org/dc/terms/description “
  4. 原始 OWL 文件的属性 rdf:resource="&rdfs;Literal" 替换为 rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"
  5. 原始 OWL 文件的属性 rdf:resource="&xsd;hexBinary" 替换为 rdf:resource="http://www.w3.org/2001/XMLSchema #hexBinary"
  6. 原始 OWL 文件的属性 rdf:resource="&xsd;string" 替换为 rdf:resource="http://www.w3.org/2001/XMLSchema #字符串”
  7. 原始 OWL 文件的属性 rdf:resource="&skos;Concept" 替换为 rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"
  8. 原始 OWL 文件的属性 rdf:resource="&skos;ConceptScheme" 替换为 rdf:resource="http://www.w3.org/2004/02/skos/core#ConceptScheme"

这种奇怪行为的原因是什么?

在我的 Eclipse 项目中,我导入了与 OWL API 3.4.2 相关的 jar 文件,该文件与 Protegé 4.3.0 中集成的版本相同。

最佳答案

问题在于从文件中读取原始本体时,未保留原始本体中的前缀。此问题已在最新版本的 OWL API 中得到修复。 3.5.2和4.0.2(4.1.0尚未发布)应该允许您找到本体格式对象中设置的前缀。

为了保证这些前缀也用于实体(例如 &rdf; 等),您应该调用

XMLWriterPreferences.getInstance().setUseNamespaceEntities(true);

保存本体之前。

请注意,这些不是语义差异 - 它们只是 XML 级别的语法差异。无论前缀是否缩短为实体,本体在语义上都是等效的。

关于java - 如何更新 OWL 本体文件以添加具有某些属性的新个体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32222908/

相关文章:

syntax - 如何定义rdfs :range target in a list of possibilities?

java - 如何防止 JAX-WS Web 方法额外标记

java - 通过 DAS 在独立 Glassfish 上配置自定义登录领域和模块

java - 我无法删除耶拿中的数据类型属性值

java - 如何将修改(OWL文件的创建、更新)保存到fuseki服务器中

semantic-web - 如何添加rdfs :label to OWLIndividual via OWLAPI?

java - OWL java对两个类使用相同的数据属性

java - 在无状态 EJB 方法中使用 Timer 来使长时间运行的操作超时

java - 如何将 L 附加到变量名

sparql - 上传一个大的 TTL 文件到 virtuoso graph