[英]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. 不幸的是,我正在努力做到这一点。
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. 因此,事情似乎变得更加困难。
I've already tried a few different approaches. 我已经尝试了几种不同的方法。
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. 我目前无法想到一种可能的方式。
Using owlapi 使用owlapi
For some reason owlapi would not work at all for me. 由于某种原因,owlapi对我完全不起作用。 It continously failed at parsing my ontology. 它一直无法解析我的本体。
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.