UNPKG

link-rdflib

Version:

an RDF library for node.js, patched for speed.

168 lines (158 loc) 4.95 kB
module.exports = parse const jsonld = require('jsonld') const N3 = require('n3') // @@ Goal: remove this dependency const NQuadsParser = require('n-quads-parser') const N3Parser = require('./n3parser') const parseRDFaDOM = require('./rdfaparser').parseRDFaDOM const RDFParser = require('./rdfxmlparser') const sparqlUpdateParser = require('./patch-parser') const BlankNode = require('./blank-node') const NamedNode = require('./named-node') const Literal = require('./literal') const Util = require('./util') /** * Parse a string and put the result into the graph kb. * Normal method is sync. * Unfortunately jsdonld is currently written to need to be called async. * Hence the mess below with executeCallback. */ function parse (str, kb, base, contentType, callback) { contentType = contentType || 'text/turtle' contentType = contentType.split(';')[0] try { if (contentType === 'text/n3' || contentType === 'text/turtle') { var p = N3Parser(kb, kb, base, base, null, null, '', null) p.loadBuf(str) executeCallback() } else if (contentType === 'application/nquads' || contentType === 'application/n-quads' || contentType === 'application/n-triples') { const nqParser = new NQuadsParser(kb) nqParser.loadBuf(str) executeCallback() } else if (contentType === 'application/rdf+xml') { var parser = new RDFParser(kb) parser.parse(Util.parseXML(str), base, kb.sym(base)) executeCallback() } else if (contentType === 'application/xhtml+xml') { parseRDFaDOM(Util.parseXML(str, {contentType: 'application/xhtml+xml'}), kb, base) executeCallback() } else if (contentType === 'text/html') { parseRDFaDOM(Util.parseXML(str, {contentType: 'text/html'}), kb, base) executeCallback() } else if (contentType === 'application/sparql-update') { // @@ we handle a subset sparqlUpdateParser(str, kb, base) executeCallback() } else if (contentType === 'application/ld+json') { var n3Parser = N3.Parser() var triples = [] if (contentType === 'application/ld+json') { var jsonDocument try { jsonDocument = JSON.parse(str) } catch (parseErr) { return callback(parseErr, null) } jsonld.toRDF(jsonDocument, {format: 'application/nquads', base}, nquadCallback) } else { nquadCallback(null, str) } } else { throw new Error("Don't know how to parse " + contentType + ' yet') } } catch (e) { executeErrorCallback(e) } parse.handled = { 'text/n3': true, 'text/turtle': true, 'application/rdf+xml': true, 'application/xhtml+xml': true, 'text/html': true, 'application/sparql-update': true, 'application/ld+json': true, 'application/nquads' : true, 'application/n-quads' : true } function executeCallback () { if (callback) { callback(null, kb) } else { return } } function executeErrorCallback (e) { if (contentType !== 'application/ld+json' || contentType !== 'application/nquads' || contentType !== 'application/n-quads') { if (callback) { callback(e, kb) } else { throw new Error('Error trying to parse <' + base + '> as ' + contentType + ':\n' + e + ':\n' + e.stack) } } } /* function setJsonLdBase (doc, base) { if (doc instanceof Array) { return } if (!('@context' in doc)) { doc['@context'] = {} } doc['@context']['@base'] = base } */ function nquadCallback (err, nquads) { if (err) { callback(err, kb) } try { n3Parser.parse(nquads, tripleCallback) } catch (err) { callback(err, kb) } } function tripleCallback (err, triple, prefixes) { if (err) { callback(err, kb) } if (triple) { triples.push(triple) } else { for (var i = 0; i < triples.length; i++) { addTriple(kb, triples[i]) } callback(null, kb) } } function addTriple (kb, triple) { var subject = createTerm(triple.subject) var predicate = createTerm(triple.predicate) var object = createTerm(triple.object) var why = null if (triple.graph) { why = createTerm(triple.graph) } kb.add(subject, predicate, object, why) } function createTerm (termString) { var value if (N3.Util.isLiteral(termString)) { value = N3.Util.getLiteralValue(termString) var language = N3.Util.getLiteralLanguage(termString) var datatype = NamedNode.find(N3.Util.getLiteralType(termString)) return Literal.find(value, language, datatype) } else if (N3.Util.isIRI(termString)) { return NamedNode.find(termString) } else if (N3.Util.isBlank(termString)) { value = termString.substring(2, termString.length) return BlankNode.find(value) } else { return null } } }