RDF/XML Ontology: 转换成JSON(-LD)树在Java

RDF/XML Ontology: Convert into JSON(-LD) Tree in Java

我正在尝试将使用 Protégé 创建的以 RDF/XML 格式存储的现有 ontology (OWL 2.0) 处理为 [=75] 中的 JSON/JSON-LD 树表示=].目标是在单独的 vue.js Web 应用程序中使用此处理后的数据以实现可视化目的。

不幸的是,我正在努力完成这件事。

我正在尝试处理的数据:

这是我正在尝试处理的 ontology(示例 ontology):

<?xml version="1.0"?>
<rdf:RDF xmlns="urn:absolute:example.com/"
     xml:base="urn:absolute:example.com/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
    <owl:Ontology rdf:about="urn:absolute:example.com/"/>



    <!-- 
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Classes
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->




    <!-- urn:absolute:example.com/#CPU -->

    <owl:Class rdf:about="urn:absolute:example.com/#CPU">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Hardware"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Enduser_Application -->

    <owl:Class rdf:about="urn:absolute:example.com/#Enduser_Application">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Software"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#GPU -->

    <owl:Class rdf:about="urn:absolute:example.com/#GPU">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Hardware"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#HDD -->

    <owl:Class rdf:about="urn:absolute:example.com/#HDD">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Storage"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Hardware -->

    <owl:Class rdf:about="urn:absolute:example.com/#Hardware"/>



    <!-- urn:absolute:example.com/#Keyboard -->

    <owl:Class rdf:about="urn:absolute:example.com/#Keyboard">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Peripherals"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Mainboard -->

    <owl:Class rdf:about="urn:absolute:example.com/#Mainboard">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Hardware"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Monitor -->

    <owl:Class rdf:about="urn:absolute:example.com/#Monitor">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Peripherals"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Mouse -->

    <owl:Class rdf:about="urn:absolute:example.com/#Mouse">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Peripherals"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Operating_System -->

    <owl:Class rdf:about="urn:absolute:example.com/#Operating_System">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Software"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Peripherals -->

    <owl:Class rdf:about="urn:absolute:example.com/#Peripherals">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Hardware"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Printer -->

    <owl:Class rdf:about="urn:absolute:example.com/#Printer">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Peripherals"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#SSD -->

    <owl:Class rdf:about="urn:absolute:example.com/#SSD">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Storage"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Software -->

    <owl:Class rdf:about="urn:absolute:example.com/#Software"/>



    <!-- urn:absolute:example.com/#Storage -->

    <owl:Class rdf:about="urn:absolute:example.com/#Storage">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Hardware"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Video_Game -->

    <owl:Class rdf:about="urn:absolute:example.com/#Video_Game">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Enduser_Application"/>
    </owl:Class>



    <!-- urn:absolute:example.com/#Word_Processor -->

    <owl:Class rdf:about="urn:absolute:example.com/#Word_Processor">
        <rdfs:subClassOf rdf:resource="urn:absolute:example.com/#Enduser_Application"/>
    </owl:Class>
</rdf:RDF>



<!-- Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi -->

这里是我想把这个 ontology 变成的结构(最好是 JSON 或 JSON-LD):

Protégé Screenshot (Imgur)

Thing
|-- Hardware
  |-- CPU
  |-- GPU
  |-- Mainboard
  |-- Peripherals
    |-- Keyboard
    |-- Monitor
    |-- Mouse
    |-- Printer
  |-- Storage
    |-- HDD
    |-- SSD
|-- Software
  |-- Enduser_Application
    |-- Video_Game
    |-- Word_Processor
  |-- Operating_System
然而,

ontology 定义了 class 及其 subclassOf 属性之间完全相反的关系。因此,事情似乎变得更加困难。

以前的方法

我已经尝试了几种不同的方法。

  1. 使用 Apache Jena

    Model model = ModelFactory.createOntologyModel();
    model.read(ontology, "OWL");
    model.write(new BufferedWriter(f), "JSON-LD");
    

    目前这似乎有效 "best"。我最终得到一个包含 JSON-LD 数据的字符串,以树的形式表示。 class 关系倒置了,但是:

    例如,顶层由键盘、显示器、鼠标、打印机等元素组成。它们各自的超classes作为子元素附加。

如果有一种方法可以使用 Apache Jena 来反转关系,那就太棒了。不过我目前想不出可行的方法。

  1. 使用 owlapi

    出于某种原因,owlapi 对我来说根本不起作用。它在解析我的 ontology.

  2. 时不断失败
  3. 使用JSON-LD成帧(使用方法1的输出)

    我注意到 JSON-LD 有一个所谓的 'framing' 功能,它本质上允许您将数据重新拟合到定义的骨架中。

    我对 JSON-LD 的 @reverse 关键字和 rdfs:subclassOf 进行了修补,希望从根本上扭转这种关系。但是,我也无法让它工作,而且我在 JSON-LD 方面也没有完全的经验。因此,我有点挣扎。

这已经让我彻夜难眠。如果有人知道这个问题的解决方案或者可以给我提示如何解决这个问题,我会很高兴。

提前非常非常感谢。

我检查了一下,我确实能够使用 OWL API 加载您的 ontology 并将其保存为 JsonLD 格式。不过,我怀疑它能否像@Ignazio 指出的那样解决您的问题。为了打印出树结构,您需要访问一个推理器,您可以从中查询包含关系。

这是加载和保存 ontology 并以树结构打印的代码示例。

private static Logger logger = LoggerFactory
        .getLogger(owl.api.test.StandaloneOWLNamedIndividualRetrievalv5.AppHardwareTest.class);
// Why This Failure marker
private static final Marker WTF_MARKER = MarkerFactory.getMarker("WTF");

static OWLReasoner reasoner;

static void printChildren(NodeSet<OWLClass> owlClasses) {
    for (Node<OWLClass> node : owlClasses) {
        logger.trace(node.getRepresentativeElement().toString());
        if (!node.getRepresentativeElement().isBottomEntity())
            printChildren(reasoner.getSubClasses(node.getRepresentativeElement()));
    }       
}

public static void main(String[] args) {
    try {
        // Setup physical IRI for storing ontology
        Path path = Paths.get(".").toAbsolutePath().normalize();
        IRI loadDocumentIRI = IRI.create("file:" + path.toFile().getAbsolutePath() + "/hardware.owl");
        IRI saveDocumentIRI = IRI.create("file:" + path.toFile().getAbsolutePath() + "/hardwareSave.txt");

        // Initialize
        OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
        OWLOntology ontology = manager.loadOntologyFromOntologyDocument(loadDocumentIRI);

        // Write to JsonLD format
        OWLDocumentFormat ontologyFormat = new RDFJsonLDDocumentFormat();
        manager.saveOntology(ontology, ontologyFormat, saveDocumentIRI);        

        // Print tree structure
        OWLReasonerFactory reasonerFactory = new JFactFactory();
        reasoner = reasonerFactory.createReasoner(ontology);            
        Node<OWLClass> top = reasoner.getTopClassNode();
        logger.trace(top.getRepresentativeElement().toString());
        printChildren(reasoner.getSubClasses(top.getRepresentativeElement()));          
    } catch (Throwable t) {
        logger.error(WTF_MARKER, t.getMessage(), t);
    }
}

希望对您有所帮助。祝你好运。