3

I am trying to parse a RDF/XML formatted document into JSON-LD in order to frame it. All using Node.js and not utilizing any web service APIs (a not too uncommon solution).

I feel that I am almost there, but my current approach feels clumsy to say the least. Putting the graph into a rdflib store and then querying it back up again gives me a strange response with some headers and no real context within the graph. Hence the doc[5]['@graph'] stuff in the middle.

var fs = require('fs')
var $rdf = require('rdflib')
var jsonld = require('jsonld')

var path = 'path_to_rdf_file'

const frame = {}

fs.readFile(path, 'utf8', function (err, data) {
    var uri = 'https://some.other.uri'
    var store = $rdf.graph()
    $rdf.parse(data, store, uri, 'application/rdf+xml')
    var a = $rdf.serialize(null, store, uri, 'application/n-quads')
    jsonld.fromRDF(a, { format: 'application/n-quads' }, (err, doc) => {
        jsonld.flatten(doc[5]['@graph'], (err, flattened) => {
            console.log(flattened)
            jsonld.frame(flattened, frame, (err, framed) => {
                resolve(framed)
            })
        })
    })
})

With all the RDF and linked data packages floating around npm, I reckon there must be a simpler solution out there that could get me from A to B.

How could I parse my RDF/XML document into a JSON-LD document without using rdflib this way?

unor
  • 92,415
  • 26
  • 211
  • 360
Fontanka16
  • 1,161
  • 1
  • 9
  • 37
  • what's wrong with using `rdflib` - I mean, it's an API designed for using RDF. How else do you want to do it? You'd have to implement your own parser for RDF/XML which is non-trivial and a serializer for the parsed RDF triples. – UninformedUser Jan 05 '19 at 08:25
  • Well, my main objection in the example is that it returns some sorrounding extra data when calling $rdf.serialize. Also, I was hoping for something like the jsonld.fromRDF function to accept RDF/XML – Fontanka16 Jan 05 '19 at 13:19
  • 1
    Ok, I think I got it. Right now, you use `rdflib` to parse RDF/XML, then you have to convert it to `n-quads` before you can use the RDF parser from `jsonld` API – UninformedUser Jan 05 '19 at 15:32
  • 1
    I guess you're not the first one asking this: see https://github.com/digitalbazaar/jsonld.js/issues/255 - looks like the will be a new Javascript lib [RDF.js](https://www.w3.org/community/rdfjs/2018/04/23/rdf-js-the-new-rdf-and-linked-data-javascript-library/) in the future which aligns RDF-Ext, N3.js and rdflib.js . Check the Github repo. Most parts are already there, at least I can see RDF/XML parser and JsonLD serializer aka Sink – UninformedUser Jan 05 '19 at 15:42
  • Thank you. I will follow that development with great interest. – Fontanka16 Jan 05 '19 at 19:08

1 Answers1

2

You can use rdflib to serialize to application/ld+json directly (rdflib uses the jsonld module internally).

var fs = require('fs')
var $rdf = require('rdflib')
var jsonld = require('jsonld')

var path = 'path_to_rdf_file'

const frame = {}

const toJSONLD = (data, uri, mimeType) => {
    return new Promise((resolve, reject) => {
        var store = $rdf.graph()
        $rdf.parse(data, store, uri, mimeType)
        $rdf.serialize(null, store, uri, 'application/ld+json', (err, jsonldData) => {
            if (err) return reject(err);
            resolve(JSON.parse(jsonldData))
        })
    })
}

fs.readFile(path, 'utf8', function (err, data) {
    var uri = 'https://some.other.uri'
    toJSONLD(data, uri, 'application/rdf+xml')
        .then((doc) => {
            jsonld.flatten(doc[5]['@graph'], (err, flattened) => {
                console.log(flattened)
                jsonld.frame(flattened, frame, (err, framed) => {
                    resolve(framed)
                })
            })
        })
})

Another way would be to equip jsonld with custom parsers for your data type using jsonld.regiserRDFParser (https://www.npmjs.com/package/jsonld#custom-rdf-parser). Allthough you would likely use rdflib for this task as well.

Philipp Gfeller
  • 1,167
  • 2
  • 15
  • 36