Comparing version 0.5.14 to 0.5.15
# jsonld ChangeLog | ||
## 0.5.15 - 2017-10-16 | ||
### Changed | ||
- **BREAKING** Use RDF JS (rdf.js.org) interfaces for internal | ||
representation of dataset and quads. This should only break | ||
code that was using undocumented internal datastructures, | ||
backwards-compat code exists to handle external RDF parsers. | ||
- Update `rdf-canonize` to dependency with native support. | ||
## 0.5.14 - 2017-10-11 | ||
@@ -4,0 +13,0 @@ |
@@ -55,4 +55,5 @@ /* | ||
for (let name in dataset) { | ||
const graph = dataset[name]; | ||
for (const quad of dataset) { | ||
// TODO: change 'name' to 'graph' | ||
const name = quad.graph.termType === 'DefaultGraph' ? '@default' : quad.graph.value; | ||
if (!(name in graphMap)) { | ||
@@ -64,54 +65,52 @@ graphMap[name] = {}; | ||
} | ||
const nodeMap = graphMap[name]; | ||
for (let ti = 0; ti < graph.length; ++ti) { | ||
const triple = graph[ti]; | ||
// get subject, predicate, object | ||
const s = triple.subject.value; | ||
const p = triple.predicate.value; | ||
const o = triple.object; | ||
// get subject, predicate, object | ||
const s = quad.subject.value; | ||
const p = quad.predicate.value; | ||
const o = quad.object; | ||
if (!(s in nodeMap)) { | ||
nodeMap[s] = { '@id': s }; | ||
} | ||
const node = nodeMap[s]; | ||
if (!(s in nodeMap)) { | ||
nodeMap[s] = { '@id': s }; | ||
} | ||
const node = nodeMap[s]; | ||
const objectIsId = o.type === 'IRI' || o.type === 'blank node'; | ||
if (objectIsId && !(o.value in nodeMap)) { | ||
nodeMap[o.value] = { '@id': o.value }; | ||
} | ||
const objectIsNode = o.termType.endsWith('Node'); | ||
if (objectIsNode && !(o.value in nodeMap)) { | ||
nodeMap[o.value] = { '@id': o.value }; | ||
} | ||
if (p === RDF_TYPE && !useRdfType && objectIsId) { | ||
util.addValue(node, '@type', o.value, { propertyIsArray: true }); | ||
continue; | ||
} | ||
if (p === RDF_TYPE && !useRdfType && objectIsNode) { | ||
util.addValue(node, '@type', o.value, { propertyIsArray: true }); | ||
continue; | ||
} | ||
const value = _RDFToObject(o, useNativeTypes); | ||
util.addValue(node, p, value, { propertyIsArray: true }); | ||
const value = _RDFToObject(o, useNativeTypes); | ||
util.addValue(node, p, value, { propertyIsArray: true }); | ||
// object may be an RDF list/partial list node but we can't know easily | ||
// until all triples are read | ||
if (objectIsId) { | ||
if (o.value === RDF_NIL) { | ||
// track rdf:nil uniquely per graph | ||
const object = nodeMap[o.value]; | ||
if (!('usages' in object)) { | ||
object.usages = []; | ||
} | ||
object.usages.push({ | ||
node: node, | ||
property: p, | ||
value: value | ||
}); | ||
} else if (o.value in referencedOnce) { | ||
// object referenced more than once | ||
referencedOnce[o.value] = false; | ||
} else { | ||
// keep track of single reference | ||
referencedOnce[o.value] = { | ||
node: node, | ||
property: p, | ||
value: value | ||
}; | ||
// object may be an RDF list/partial list node but we can't know easily | ||
// until all triples are read | ||
if (objectIsNode) { | ||
if (o.value === RDF_NIL) { | ||
// track rdf:nil uniquely per graph | ||
const object = nodeMap[o.value]; | ||
if (!('usages' in object)) { | ||
object.usages = []; | ||
} | ||
object.usages.push({ | ||
node: node, | ||
property: p, | ||
value: value | ||
}); | ||
} else if (o.value in referencedOnce) { | ||
// object referenced more than once | ||
referencedOnce[o.value] = false; | ||
} else { | ||
// keep track of single reference | ||
referencedOnce[o.value] = { | ||
node: node, | ||
property: p, | ||
value: value | ||
}; | ||
} | ||
@@ -121,2 +120,67 @@ } | ||
/* | ||
for(let name in dataset) { | ||
const graph = dataset[name]; | ||
if(!(name in graphMap)) { | ||
graphMap[name] = {}; | ||
} | ||
if(name !== '@default' && !(name in defaultGraph)) { | ||
defaultGraph[name] = {'@id': name}; | ||
} | ||
const nodeMap = graphMap[name]; | ||
for(let ti = 0; ti < graph.length; ++ti) { | ||
const triple = graph[ti]; | ||
// get subject, predicate, object | ||
const s = triple.subject.value; | ||
const p = triple.predicate.value; | ||
const o = triple.object; | ||
if(!(s in nodeMap)) { | ||
nodeMap[s] = {'@id': s}; | ||
} | ||
const node = nodeMap[s]; | ||
const objectIsId = (o.type === 'IRI' || o.type === 'blank node'); | ||
if(objectIsId && !(o.value in nodeMap)) { | ||
nodeMap[o.value] = {'@id': o.value}; | ||
} | ||
if(p === RDF_TYPE && !useRdfType && objectIsId) { | ||
util.addValue(node, '@type', o.value, {propertyIsArray: true}); | ||
continue; | ||
} | ||
const value = _RDFToObject(o, useNativeTypes); | ||
util.addValue(node, p, value, {propertyIsArray: true}); | ||
// object may be an RDF list/partial list node but we can't know easily | ||
// until all triples are read | ||
if(objectIsId) { | ||
if(o.value === RDF_NIL) { | ||
// track rdf:nil uniquely per graph | ||
const object = nodeMap[o.value]; | ||
if(!('usages' in object)) { | ||
object.usages = []; | ||
} | ||
object.usages.push({ | ||
node: node, | ||
property: p, | ||
value: value | ||
}); | ||
} else if(o.value in referencedOnce) { | ||
// object referenced more than once | ||
referencedOnce[o.value] = false; | ||
} else { | ||
// keep track of single reference | ||
referencedOnce[o.value] = { | ||
node: node, | ||
property: p, | ||
value: value | ||
}; | ||
} | ||
} | ||
} | ||
}*/ | ||
// convert linked lists to @list arrays | ||
@@ -133,4 +197,3 @@ for (let name in graphMap) { | ||
const nil = graphObject[RDF_NIL]; | ||
for (let i = 0; i < nil.usages.length; ++i) { | ||
let usage = nil.usages[i]; | ||
for (let usage of nil.usages) { | ||
let node = usage.node; | ||
@@ -161,3 +224,3 @@ let property = usage.property; | ||
// if node is not a blank node, then list head found | ||
if (node['@id'].indexOf('_:') !== 0) { | ||
if (!graphTypes.isBlankNode(node)) { | ||
break; | ||
@@ -185,4 +248,4 @@ } | ||
head['@list'] = list.reverse(); | ||
for (let j = 0; j < listNodes.length; ++j) { | ||
delete graphObject[listNodes[j]]; | ||
for (const listNode of listNodes) { | ||
delete graphObject[listNode]; | ||
} | ||
@@ -196,4 +259,3 @@ } | ||
const subjects = Object.keys(defaultGraph).sort(); | ||
for (let i = 0; i < subjects.length; ++i) { | ||
const subject = subjects[i]; | ||
for (const subject of subjects) { | ||
const node = defaultGraph[subject]; | ||
@@ -203,8 +265,8 @@ if (subject in graphMap) { | ||
const graphObject = graphMap[subject]; | ||
const subjects_ = Object.keys(graphObject).sort(); | ||
for (let si = 0; si < subjects_.length; ++si) { | ||
const node_ = graphObject[subjects_[si]]; | ||
const graphSubjects = Object.keys(graphObject).sort(); | ||
for (const graphSubject of graphSubjects) { | ||
const node = graphObject[graphSubject]; | ||
// only add full subjects to top-level | ||
if (!graphTypes.isSubjectReference(node_)) { | ||
graph.push(node_); | ||
if (!graphTypes.isSubjectReference(node)) { | ||
graph.push(node); | ||
} | ||
@@ -236,4 +298,4 @@ } | ||
function _RDFToObject(o, useNativeTypes) { | ||
// convert IRI/blank node object to JSON-LD | ||
if (o.type === 'IRI' || o.type === 'blank node') { | ||
// convert NamedNode/BlankNode object to JSON-LD | ||
if (o.termType.endsWith('Node')) { | ||
return { '@id': o.value }; | ||
@@ -249,3 +311,3 @@ } | ||
} else { | ||
let type = o.datatype; | ||
let type = o.datatype.value; | ||
if (!type) { | ||
@@ -252,0 +314,0 @@ type = XSD_STRING; |
@@ -640,2 +640,4 @@ 'use strict'; | ||
// TODO: call `normalizeAsyncFn` on parser fn | ||
// rdfParser can be callback, promise-based, or synchronous | ||
@@ -658,3 +660,10 @@ let parsedDataset; | ||
return _fromRDF((yield parsedDataset), options); | ||
parsedDataset = yield parsedDataset; | ||
// back-compat with old parsers that produced legacy dataset format | ||
if (!Array.isArray(parsedDataset)) { | ||
parsedDataset = NQuads.legacyDatasetToQuads(dataset); | ||
} | ||
return _fromRDF(parsedDataset, options); | ||
}); | ||
@@ -661,0 +670,0 @@ |
@@ -58,11 +58,22 @@ /* | ||
const dataset = {}; | ||
const dataset = []; | ||
const graphNames = Object.keys(nodeMap).sort(); | ||
for (let i = 0; i < graphNames.length; ++i) { | ||
const graphName = graphNames[i]; | ||
// skip relative IRIs | ||
if (graphName === '@default' || _isAbsoluteIri(graphName)) { | ||
dataset[graphName] = _graphToRDF(nodeMap[graphName], issuer, options); | ||
for (const graphName of graphNames) { | ||
let graphTerm; | ||
if (graphName === '@default') { | ||
graphTerm = { termType: 'DefaultGraph', value: '' }; | ||
} else if (_isAbsoluteIri(graphName)) { | ||
if (graphName.startsWith('_:')) { | ||
graphTerm = { termType: 'BlankNode' }; | ||
} else { | ||
graphTerm = { termType: 'NamedNode' }; | ||
} | ||
graphTerm.value = graphName; | ||
} else { | ||
// skip relative IRIs (not valid RDF) | ||
continue; | ||
} | ||
_graphToRDF(dataset, nodeMap[graphName], graphTerm, issuer, options); | ||
} | ||
return dataset; | ||
@@ -72,5 +83,7 @@ }; | ||
/** | ||
* Creates an array of RDF triples for the given graph. | ||
* Adds RDF quads for a particular graph to the given dataset. | ||
* | ||
* @param graph the graph to create RDF triples for. | ||
* @param dataset the dataset to append RDF quads to. | ||
* @param graph the graph to create RDF quads for. | ||
* @param graphTerm the graph term for each quad. | ||
* @param issuer a IdentifierIssuer for assigning blank node names. | ||
@@ -81,5 +94,3 @@ * @param options the RDF serialization options. | ||
*/ | ||
function _graphToRDF(graph, issuer, options) { | ||
const rval = []; | ||
function _graphToRDF(dataset, graph, graphTerm, issuer, options) { | ||
const ids = Object.keys(graph).sort(); | ||
@@ -90,4 +101,3 @@ for (let i = 0; i < ids.length; ++i) { | ||
const properties = Object.keys(node).sort(); | ||
for (let pi = 0; pi < properties.length; ++pi) { | ||
let property = properties[pi]; | ||
for (let property of properties) { | ||
const items = node[property]; | ||
@@ -100,11 +110,10 @@ if (property === '@type') { | ||
for (let ii = 0; ii < items.length; ++ii) { | ||
const item = items[ii]; | ||
for (const item of items) { | ||
// RDF subject | ||
const subject = {}; | ||
subject.type = id.indexOf('_:') === 0 ? 'blank node' : 'IRI'; | ||
subject.value = id; | ||
const subject = { | ||
termType: id.startsWith('_:') ? 'BlankNode' : 'NamedNode', | ||
value: id | ||
}; | ||
// skip relative IRI subjects | ||
// skip relative IRI subjects (not valid RDF) | ||
if (!_isAbsoluteIri(id)) { | ||
@@ -115,7 +124,8 @@ continue; | ||
// RDF predicate | ||
const predicate = {}; | ||
predicate.type = property.indexOf('_:') === 0 ? 'blank node' : 'IRI'; | ||
predicate.value = property; | ||
const predicate = { | ||
termType: property.startsWith('_:') ? 'BlankNode' : 'NamedNode', | ||
value: property | ||
}; | ||
// skip relative IRI predicates | ||
// skip relative IRI predicates (not valid RDF) | ||
if (!_isAbsoluteIri(property)) { | ||
@@ -126,3 +136,3 @@ continue; | ||
// skip blank node predicates unless producing generalized RDF | ||
if (predicate.type === 'blank node' && !options.produceGeneralizedRdf) { | ||
if (predicate.termType === 'BlankNode' && !options.produceGeneralizedRdf) { | ||
continue; | ||
@@ -133,3 +143,3 @@ } | ||
if (graphTypes.isList(item)) { | ||
_listToRDF(item['@list'], issuer, subject, predicate, rval); | ||
_listToRDF(item['@list'], issuer, subject, predicate, dataset, graphTerm); | ||
} else { | ||
@@ -140,3 +150,8 @@ // convert value or node object to triple | ||
if (object) { | ||
rval.push({ subject: subject, predicate: predicate, object: object }); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: object, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -147,8 +162,6 @@ } | ||
} | ||
return rval; | ||
} | ||
/** | ||
* Converts a @list value into linked list of blank node RDF triples | ||
* Converts a @list value into linked list of blank node RDF quads | ||
* (an RDF collection). | ||
@@ -160,15 +173,19 @@ * | ||
* @param predicate the predicate for the head of the list. | ||
* @param triples the array of triples to append to. | ||
* @param dataset the array of quads to append to. | ||
* @param graphTerm the graph term for each quad. | ||
*/ | ||
function _listToRDF(list, issuer, subject, predicate, triples) { | ||
const first = { type: 'IRI', value: RDF_FIRST }; | ||
const rest = { type: 'IRI', value: RDF_REST }; | ||
const nil = { type: 'IRI', value: RDF_NIL }; | ||
function _listToRDF(list, issuer, subject, predicate, dataset, graphTerm) { | ||
const first = { termType: 'NamedNode', value: RDF_FIRST }; | ||
const rest = { termType: 'NamedNode', value: RDF_REST }; | ||
const nil = { termType: 'NamedNode', value: RDF_NIL }; | ||
for (let i = 0; i < list.length; ++i) { | ||
const item = list[i]; | ||
for (const item of list) { | ||
const blankNode = { termType: 'BlankNode', value: issuer.getId() }; | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: blankNode, | ||
graph: graphTerm | ||
}); | ||
const blankNode = { type: 'blank node', value: issuer.getId() }; | ||
triples.push({ subject: subject, predicate: predicate, object: blankNode }); | ||
subject = blankNode; | ||
@@ -180,3 +197,8 @@ predicate = first; | ||
if (object) { | ||
triples.push({ subject: subject, predicate: predicate, object: object }); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: object, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -187,3 +209,8 @@ | ||
triples.push({ subject: subject, predicate: predicate, object: nil }); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: nil, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -204,3 +231,7 @@ | ||
if (graphTypes.isValue(item)) { | ||
object.type = 'literal'; | ||
object.termType = 'Literal'; | ||
object.value = undefined; | ||
object.datatype = { | ||
termType: 'NamedNode' | ||
}; | ||
let value = item['@value']; | ||
@@ -212,3 +243,3 @@ const datatype = item['@type'] || null; | ||
object.value = value.toString(); | ||
object.datatype = datatype || XSD_BOOLEAN; | ||
object.datatype.value = datatype || XSD_BOOLEAN; | ||
} else if (types.isDouble(value) || datatype === XSD_DOUBLE) { | ||
@@ -220,13 +251,13 @@ if (!types.isDouble(value)) { | ||
object.value = value.toExponential(15).replace(/(\d)0*e\+?/, '$1E'); | ||
object.datatype = datatype || XSD_DOUBLE; | ||
object.datatype.value = datatype || XSD_DOUBLE; | ||
} else if (types.isNumber(value)) { | ||
object.value = value.toFixed(0); | ||
object.datatype = datatype || XSD_INTEGER; | ||
object.datatype.value = datatype || XSD_INTEGER; | ||
} else if ('@language' in item) { | ||
object.value = value; | ||
object.datatype = datatype || RDF_LANGSTRING; | ||
object.datatype.value = datatype || RDF_LANGSTRING; | ||
object.language = item['@language']; | ||
} else { | ||
object.value = value; | ||
object.datatype = datatype || XSD_STRING; | ||
object.datatype.value = datatype || XSD_STRING; | ||
} | ||
@@ -236,8 +267,8 @@ } else { | ||
const id = types.isObject(item) ? item['@id'] : item; | ||
object.type = id.indexOf('_:') === 0 ? 'blank node' : 'IRI'; | ||
object.termType = id.startsWith('_:') ? 'BlankNode' : 'NamedNode'; | ||
object.value = id; | ||
} | ||
// skip relative IRIs | ||
if (object.type === 'IRI' && !_isAbsoluteIri(object.value)) { | ||
// skip relative IRIs, not valid RDF | ||
if (object.termType === 'NamedNode' && !_isAbsoluteIri(object.value)) { | ||
return null; | ||
@@ -244,0 +275,0 @@ } |
@@ -47,2 +47,67 @@ /* | ||
for(const quad of dataset) { | ||
// TODO: change 'name' to 'graph' | ||
const name = (quad.graph.termType === 'DefaultGraph') ? | ||
'@default': quad.graph.value; | ||
if(!(name in graphMap)) { | ||
graphMap[name] = {}; | ||
} | ||
if(name !== '@default' && !(name in defaultGraph)) { | ||
defaultGraph[name] = {'@id': name}; | ||
} | ||
const nodeMap = graphMap[name]; | ||
// get subject, predicate, object | ||
const s = quad.subject.value; | ||
const p = quad.predicate.value; | ||
const o = quad.object; | ||
if(!(s in nodeMap)) { | ||
nodeMap[s] = {'@id': s}; | ||
} | ||
const node = nodeMap[s]; | ||
const objectIsNode = o.termType.endsWith('Node'); | ||
if(objectIsNode && !(o.value in nodeMap)) { | ||
nodeMap[o.value] = {'@id': o.value}; | ||
} | ||
if(p === RDF_TYPE && !useRdfType && objectIsNode) { | ||
util.addValue(node, '@type', o.value, {propertyIsArray: true}); | ||
continue; | ||
} | ||
const value = _RDFToObject(o, useNativeTypes); | ||
util.addValue(node, p, value, {propertyIsArray: true}); | ||
// object may be an RDF list/partial list node but we can't know easily | ||
// until all triples are read | ||
if(objectIsNode) { | ||
if(o.value === RDF_NIL) { | ||
// track rdf:nil uniquely per graph | ||
const object = nodeMap[o.value]; | ||
if(!('usages' in object)) { | ||
object.usages = []; | ||
} | ||
object.usages.push({ | ||
node: node, | ||
property: p, | ||
value: value | ||
}); | ||
} else if(o.value in referencedOnce) { | ||
// object referenced more than once | ||
referencedOnce[o.value] = false; | ||
} else { | ||
// keep track of single reference | ||
referencedOnce[o.value] = { | ||
node: node, | ||
property: p, | ||
value: value | ||
}; | ||
} | ||
} | ||
} | ||
/* | ||
for(let name in dataset) { | ||
@@ -110,3 +175,3 @@ const graph = dataset[name]; | ||
} | ||
} | ||
}*/ | ||
@@ -124,4 +189,3 @@ // convert linked lists to @list arrays | ||
const nil = graphObject[RDF_NIL]; | ||
for(let i = 0; i < nil.usages.length; ++i) { | ||
let usage = nil.usages[i]; | ||
for(let usage of nil.usages) { | ||
let node = usage.node; | ||
@@ -158,3 +222,3 @@ let property = usage.property; | ||
// if node is not a blank node, then list head found | ||
if(node['@id'].indexOf('_:') !== 0) { | ||
if(!graphTypes.isBlankNode(node)) { | ||
break; | ||
@@ -182,4 +246,4 @@ } | ||
head['@list'] = list.reverse(); | ||
for(let j = 0; j < listNodes.length; ++j) { | ||
delete graphObject[listNodes[j]]; | ||
for(const listNode of listNodes) { | ||
delete graphObject[listNode]; | ||
} | ||
@@ -193,4 +257,3 @@ } | ||
const subjects = Object.keys(defaultGraph).sort(); | ||
for(let i = 0; i < subjects.length; ++i) { | ||
const subject = subjects[i]; | ||
for(const subject of subjects) { | ||
const node = defaultGraph[subject]; | ||
@@ -200,8 +263,8 @@ if(subject in graphMap) { | ||
const graphObject = graphMap[subject]; | ||
const subjects_ = Object.keys(graphObject).sort(); | ||
for(let si = 0; si < subjects_.length; ++si) { | ||
const node_ = graphObject[subjects_[si]]; | ||
const graphSubjects = Object.keys(graphObject).sort(); | ||
for(const graphSubject of graphSubjects) { | ||
const node = graphObject[graphSubject]; | ||
// only add full subjects to top-level | ||
if(!graphTypes.isSubjectReference(node_)) { | ||
graph.push(node_); | ||
if(!graphTypes.isSubjectReference(node)) { | ||
graph.push(node); | ||
} | ||
@@ -228,4 +291,4 @@ } | ||
function _RDFToObject(o, useNativeTypes) { | ||
// convert IRI/blank node object to JSON-LD | ||
if(o.type === 'IRI' || o.type === 'blank node') { | ||
// convert NamedNode/BlankNode object to JSON-LD | ||
if(o.termType.endsWith('Node')) { | ||
return {'@id': o.value}; | ||
@@ -241,3 +304,3 @@ } | ||
} else { | ||
let type = o.datatype; | ||
let type = o.datatype.value; | ||
if(!type) { | ||
@@ -244,0 +307,0 @@ type = XSD_STRING; |
@@ -588,2 +588,4 @@ /** | ||
// TODO: call `normalizeAsyncFn` on parser fn | ||
// rdfParser can be callback, promise-based, or synchronous | ||
@@ -606,3 +608,10 @@ let parsedDataset; | ||
return _fromRDF(await parsedDataset, options); | ||
parsedDataset = await parsedDataset; | ||
// back-compat with old parsers that produced legacy dataset format | ||
if(!Array.isArray(parsedDataset)) { | ||
parsedDataset = NQuads.legacyDatasetToQuads(dataset); | ||
} | ||
return _fromRDF(parsedDataset, options); | ||
}); | ||
@@ -609,0 +618,0 @@ |
135
lib/toRdf.js
@@ -52,11 +52,22 @@ /* | ||
const dataset = {}; | ||
const dataset = []; | ||
const graphNames = Object.keys(nodeMap).sort(); | ||
for(let i = 0; i < graphNames.length; ++i) { | ||
const graphName = graphNames[i]; | ||
// skip relative IRIs | ||
if(graphName === '@default' || _isAbsoluteIri(graphName)) { | ||
dataset[graphName] = _graphToRDF(nodeMap[graphName], issuer, options); | ||
for(const graphName of graphNames) { | ||
let graphTerm; | ||
if(graphName === '@default') { | ||
graphTerm = {termType: 'DefaultGraph', value: ''}; | ||
} else if(_isAbsoluteIri(graphName)) { | ||
if(graphName.startsWith('_:')) { | ||
graphTerm = {termType: 'BlankNode'}; | ||
} else { | ||
graphTerm = {termType: 'NamedNode'}; | ||
} | ||
graphTerm.value = graphName; | ||
} else { | ||
// skip relative IRIs (not valid RDF) | ||
continue; | ||
} | ||
_graphToRDF(dataset, nodeMap[graphName], graphTerm, issuer, options); | ||
} | ||
return dataset; | ||
@@ -66,5 +77,7 @@ }; | ||
/** | ||
* Creates an array of RDF triples for the given graph. | ||
* Adds RDF quads for a particular graph to the given dataset. | ||
* | ||
* @param graph the graph to create RDF triples for. | ||
* @param dataset the dataset to append RDF quads to. | ||
* @param graph the graph to create RDF quads for. | ||
* @param graphTerm the graph term for each quad. | ||
* @param issuer a IdentifierIssuer for assigning blank node names. | ||
@@ -75,5 +88,3 @@ * @param options the RDF serialization options. | ||
*/ | ||
function _graphToRDF(graph, issuer, options) { | ||
const rval = []; | ||
function _graphToRDF(dataset, graph, graphTerm, issuer, options) { | ||
const ids = Object.keys(graph).sort(); | ||
@@ -84,4 +95,3 @@ for(let i = 0; i < ids.length; ++i) { | ||
const properties = Object.keys(node).sort(); | ||
for(let pi = 0; pi < properties.length; ++pi) { | ||
let property = properties[pi]; | ||
for(let property of properties) { | ||
const items = node[property]; | ||
@@ -94,11 +104,10 @@ if(property === '@type') { | ||
for(let ii = 0; ii < items.length; ++ii) { | ||
const item = items[ii]; | ||
for(const item of items) { | ||
// RDF subject | ||
const subject = {}; | ||
subject.type = (id.indexOf('_:') === 0) ? 'blank node' : 'IRI'; | ||
subject.value = id; | ||
const subject = { | ||
termType: id.startsWith('_:') ? 'BlankNode' : 'NamedNode', | ||
value: id | ||
}; | ||
// skip relative IRI subjects | ||
// skip relative IRI subjects (not valid RDF) | ||
if(!_isAbsoluteIri(id)) { | ||
@@ -109,7 +118,8 @@ continue; | ||
// RDF predicate | ||
const predicate = {}; | ||
predicate.type = (property.indexOf('_:') === 0) ? 'blank node' : 'IRI'; | ||
predicate.value = property; | ||
const predicate = { | ||
termType: property.startsWith('_:') ? 'BlankNode' : 'NamedNode', | ||
value: property | ||
}; | ||
// skip relative IRI predicates | ||
// skip relative IRI predicates (not valid RDF) | ||
if(!_isAbsoluteIri(property)) { | ||
@@ -120,3 +130,4 @@ continue; | ||
// skip blank node predicates unless producing generalized RDF | ||
if(predicate.type === 'blank node' && !options.produceGeneralizedRdf) { | ||
if(predicate.termType === 'BlankNode' && | ||
!options.produceGeneralizedRdf) { | ||
continue; | ||
@@ -127,3 +138,4 @@ } | ||
if(graphTypes.isList(item)) { | ||
_listToRDF(item['@list'], issuer, subject, predicate, rval); | ||
_listToRDF( | ||
item['@list'], issuer, subject, predicate, dataset, graphTerm); | ||
} else { | ||
@@ -134,3 +146,8 @@ // convert value or node object to triple | ||
if(object) { | ||
rval.push({subject: subject, predicate: predicate, object: object}); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: object, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -141,8 +158,6 @@ } | ||
} | ||
return rval; | ||
} | ||
/** | ||
* Converts a @list value into linked list of blank node RDF triples | ||
* Converts a @list value into linked list of blank node RDF quads | ||
* (an RDF collection). | ||
@@ -154,15 +169,19 @@ * | ||
* @param predicate the predicate for the head of the list. | ||
* @param triples the array of triples to append to. | ||
* @param dataset the array of quads to append to. | ||
* @param graphTerm the graph term for each quad. | ||
*/ | ||
function _listToRDF(list, issuer, subject, predicate, triples) { | ||
const first = {type: 'IRI', value: RDF_FIRST}; | ||
const rest = {type: 'IRI', value: RDF_REST}; | ||
const nil = {type: 'IRI', value: RDF_NIL}; | ||
function _listToRDF(list, issuer, subject, predicate, dataset, graphTerm) { | ||
const first = {termType: 'NamedNode', value: RDF_FIRST}; | ||
const rest = {termType: 'NamedNode', value: RDF_REST}; | ||
const nil = {termType: 'NamedNode', value: RDF_NIL}; | ||
for(let i = 0; i < list.length; ++i) { | ||
const item = list[i]; | ||
for(const item of list) { | ||
const blankNode = {termType: 'BlankNode', value: issuer.getId()}; | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: blankNode, | ||
graph: graphTerm | ||
}); | ||
const blankNode = {type: 'blank node', value: issuer.getId()}; | ||
triples.push({subject: subject, predicate: predicate, object: blankNode}); | ||
subject = blankNode; | ||
@@ -174,3 +193,8 @@ predicate = first; | ||
if(object) { | ||
triples.push({subject: subject, predicate: predicate, object: object}); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: object, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -181,3 +205,8 @@ | ||
triples.push({subject: subject, predicate: predicate, object: nil}); | ||
dataset.push({ | ||
subject: subject, | ||
predicate: predicate, | ||
object: nil, | ||
graph: graphTerm | ||
}); | ||
} | ||
@@ -198,3 +227,7 @@ | ||
if(graphTypes.isValue(item)) { | ||
object.type = 'literal'; | ||
object.termType = 'Literal'; | ||
object.value = undefined; | ||
object.datatype = { | ||
termType: 'NamedNode' | ||
}; | ||
let value = item['@value']; | ||
@@ -206,3 +239,3 @@ const datatype = item['@type'] || null; | ||
object.value = value.toString(); | ||
object.datatype = datatype || XSD_BOOLEAN; | ||
object.datatype.value = datatype || XSD_BOOLEAN; | ||
} else if(types.isDouble(value) || datatype === XSD_DOUBLE) { | ||
@@ -214,13 +247,13 @@ if(!types.isDouble(value)) { | ||
object.value = value.toExponential(15).replace(/(\d)0*e\+?/, '$1E'); | ||
object.datatype = datatype || XSD_DOUBLE; | ||
object.datatype.value = datatype || XSD_DOUBLE; | ||
} else if(types.isNumber(value)) { | ||
object.value = value.toFixed(0); | ||
object.datatype = datatype || XSD_INTEGER; | ||
object.datatype.value = datatype || XSD_INTEGER; | ||
} else if('@language' in item) { | ||
object.value = value; | ||
object.datatype = datatype || RDF_LANGSTRING; | ||
object.datatype.value = datatype || RDF_LANGSTRING; | ||
object.language = item['@language']; | ||
} else { | ||
object.value = value; | ||
object.datatype = datatype || XSD_STRING; | ||
object.datatype.value = datatype || XSD_STRING; | ||
} | ||
@@ -230,8 +263,8 @@ } else { | ||
const id = types.isObject(item) ? item['@id'] : item; | ||
object.type = (id.indexOf('_:') === 0) ? 'blank node' : 'IRI'; | ||
object.termType = id.startsWith('_:') ? 'BlankNode' : 'NamedNode'; | ||
object.value = id; | ||
} | ||
// skip relative IRIs | ||
if(object.type === 'IRI' && !_isAbsoluteIri(object.value)) { | ||
// skip relative IRIs, not valid RDF | ||
if(object.termType === 'NamedNode' && !_isAbsoluteIri(object.value)) { | ||
return null; | ||
@@ -238,0 +271,0 @@ } |
{ | ||
"name": "jsonld", | ||
"version": "0.5.14", | ||
"version": "0.5.15", | ||
"description": "A JSON-LD Processor and API implementation in JavaScript.", | ||
@@ -35,3 +35,3 @@ "homepage": "https://github.com/digitalbazaar/jsonld.js", | ||
"pkginfo": "^0.4.1", | ||
"rdf-canonize": "^0.1.5", | ||
"rdf-canonize": "^0.2.1", | ||
"request": "^2.83.0", | ||
@@ -52,3 +52,3 @@ "semver": "^5.4.1", | ||
"cors": "^2.7.1", | ||
"express": "^4.16.0", | ||
"express": "^4.16.2", | ||
"fs-extra": "^4.0.2", | ||
@@ -73,7 +73,7 @@ "istanbul": "^0.4.3", | ||
"karma-tap-reporter": "0.0.6", | ||
"karma-webpack": "^2.0.4", | ||
"karma-webpack": "^2.0.5", | ||
"mocha": "^3.5.3", | ||
"mocha-lcov-reporter": "^1.3.0", | ||
"regenerator-runtime": "^0.11.0", | ||
"webpack": "^3.6.0", | ||
"webpack": "^3.7.1", | ||
"webpack-merge": "^4.1.0" | ||
@@ -80,0 +80,0 @@ }, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1131080
26570
+ Addedbindings@1.5.0(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addednan@2.22.0(transitive)
+ Addedrdf-canonize@0.2.5(transitive)
- Removedes6-promise@2.0.1(transitive)
- Removedrdf-canonize@0.1.5(transitive)
Updatedrdf-canonize@^0.2.1