简体   繁体   English

RDF / XML本体:用Java转换为JSON(-LD)树

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

I am trying to process an existing ontology (OWL 2.0) stored in the RDF/XML format created using Protégé to a JSON/JSON-LD tree representation in Java. 我正在尝试处理以Protégé创建的RDF / XML格式存储的现有本体(OWL 2.0),以Java中的JSON / JSON-LD树表示形式。 The goal is to use this processed data in a separate vue.js web application for visualization purposes. 目标是在单独的vue.js Web应用程序中使用此处理后的数据进行可视化。

Unfortunately, I am struggling to get this done. 不幸的是,我正在努力做到这一点。

Data I am trying to process: 我正在尝试处理的数据:

Here's the ontology I am trying to process (example 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 -->

Here is the structure I want to turn this ontology into (preferably in JSON or JSON-LD): 这是我想将此本体转换成的结构(最好是在JSON或JSON-LD中):

Protégé Screenshot (Imgur) Protégé屏幕截图(Imgur)

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

The ontology is however defining the exact opposite relation between classes with their subclassOf attributes. 但是,本体通过其subclassOf属性定义了类之间完全相反的关系。 Thus, things seem to get more difficult. 因此,事情似乎变得更加困难。

Previous approaches 先前的方法

I've already tried a few different approaches. 我已经尝试了几种不同的方法。

  1. Using Apache Jena 使用Apache Jena

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

    This seems to work "best" currently. 目前,这似乎工作“最佳”。 I eventually get a String containing JSON-LD data in a tree representation. 我最终得到一个以树表示形式包含JSON-LD数据的字符串。 The class relationships are inverted, though: 但是,类关系是相反的:

    For instance, the top layer consists of the elements Keyboard, Monitor, Mouse, Printer, and so on. 例如,顶层由元素Keyboard,Monitor,Mouse,Printer等组成。 Their respective superclasses are attached as child elements. 它们各自的超类作为子元素附加。

If there's a way to reverse the relationships using Apache Jena, that'd be pretty cool. 如果有一种使用Apache Jena来逆转关系的方法,那将非常酷。 I currently can't think of a possible way though. 我目前无法想到一种可能的方式。

  1. Using owlapi 使用owlapi

    For some reason owlapi would not work at all for me. 由于某种原因,owlapi对我完全不起作用。 It continously failed at parsing my ontology. 它一直无法解析我的本体。

  2. Using JSON-LD Framing (using the output from approach 1) 使用JSON-LD框架(使用方法1的输出)

    I noticed that JSON-LD has a so-called 'framing' feature which essentially allows you to re-fit data into a defined skeleton. 我注意到JSON-LD具有所谓的“成帧”功能,该功能实质上允许您将数据重新适配到已定义的框架中。

    I tinkered around with JSON-LD's @reverse keyword in conjunction with rdfs:subclassOf hoping to essentially have the relationship reversed. 我修改了JSON-LD的@reverse关键字以及rdfs:subclassOf希望从本质上扭转这种关系。 However, I can't get that to work either and I am not exactly experienced in JSON-LD. 但是,我也无法使它正常工作,而且我对JSON-LD也不完全了解。 Hence, I am somewhat struggling. 因此,我有些挣扎。

This has led to some sleepless nights for me already. 这已经给我带来了一些不眠之夜。 I'd be SO happy if someone knows a solution to this or just can give me hints on how to solve this problem. 如果有人知道解决方案,或者可以给我提示如何解决此问题,我将非常高兴。

Thank you very, very much in advance. 非常非常感谢。

I checked and I have indeed been able to load your ontology using the OWL API and save it into JsonLD format. 我检查了一下,确实可以使用OWL API加载您的本体并将其保存为JsonLD格式。 Though, I doubt it will solve your problem as @Ignazio pointed out. 不过,正如@Ignazio指出的那样,我怀疑它能否解决您的问题。 In order to print out the tree structure you need access to a reasoner from which you can query subsumption relations. 为了打印出树形结构,您需要访问一个推理器,从中可以查询包含关系。

Here is a code sample loading and saving your ontology and printing it in a tree structure. 这是一个代码示例,用于加载和保存本体并将其打印为树形结构。

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);
    }
}

I hope it helps. 希望对您有所帮助。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM