Skip to content

Commit

Permalink
compaction/concise
Browse files Browse the repository at this point in the history
  • Loading branch information
wagmarcel committed Nov 1, 2023
1 parent 4d4db56 commit faad3f6
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 24 deletions.
136 changes: 112 additions & 24 deletions jsonldConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,21 @@ const N3 = require('n3');
const url = require('url');
const { DataFactory } = N3;
const { namedNode, literal, blankNode, defaultGraph, quad } = DataFactory;
const { URL } = require('url'); // Import the URL module
//const { URL } = require('url'); // Import the URL module
const ContextParser = require('jsonld-context-parser').ContextParser;
const ContextUtil = require('jsonld-context-parser').Util;
const myParser = new ContextParser();
const jsonld = require('jsonld');
const exp = require('constants');

const RDF = $rdf.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
const SHACL = $rdf.Namespace('http://www.w3.org/ns/shacl#');
const IFFK = $rdf.Namespace('https://industry-fusion.org/knowledge/v0.1/');
const argv = yargs
.usage('Usage: $0 <json-file> [options]')
.option('compacted', {
alias: 'm',
description: 'Create compacted form (without switch: expanded form)',
demandOption: false,
type: 'string'
})
.option('concise', {
alias: 'n',
description: 'Create concise from (without switch: normalized form) ',
description: 'Create concise/compacted from',
demandOption: false,
type: 'string'
})
Expand All @@ -61,7 +56,13 @@ const argv = yargs
const jsonFileName = argv['_'][0];
const jsonText = fs.readFileSync(jsonFileName, 'utf8');
const jsonObj = JSON.parse(jsonText);
var jsonArr;

if (!Array.isArray(jsonObj)){
jsonArr = [jsonObj]
} else {
jsonArr = jsonObj
}

function assertNoContext(jsonObj) {
if (Array.isArray(jsonObj)) {
Expand All @@ -79,27 +80,114 @@ function assertNoContext(jsonObj) {
}
}

(async (file) => {
if (! (argv.m === undefined)) {
if (argv.c === undefined) {
console.error("Error: Context must be defined externally for compaction. Exiting!");
process.exit(1);

// Check if every object in array whether it has Context
function hasContexts(jsonArr) {
jsonArr.forEach(jsonObj => {
if (!("@context" in jsonObj)) {
return false
}
assertNoContext(jsonObj)
})
return true;
}

const compacted = await jsonld.compact(jsonObj, argv.c);
console.log(JSON.stringify(compacted, null, 2));
} else {
if (argv.c !== undefined) {
console.warn("Warning: Context must not be defined externally for expansion. Ignoring external context!");

function loadContextFromFile(fileName) {
const context = fs.readFileSync(fileName, 'utf8');
const contextParsed = JSON.parse(context)
return contextParsed;
}


// Merge Contexts
function mergeContexts(jsonArr, context) {
function mergeContext(localContext, context) {
var mergedContext = [];
if (Array.isArray(localContext)){
mergedContext = [localContext];
}
if (!("@context" in jsonObj)) {
console.error("Error: Context must be defined internally for expansion. Exiting!");
if (context === undefined) {
if (mergedContext.length === 0) {
return null;
}
return mergedContext;
} else if (!Array.isArray(context)) {
context = [context];
}
context.forEach(c => {
if (typeof(c) !== "string" || mergedContext.find(x => c === x) === undefined) {
mergedContext.push(c)
}
})
return mergedContext;
}
const parseContextUrl = url.parse(context, true);
if (parseContextUrl.protocol === "file:"){
context = loadContextFromFile(parseContextUrl.path);
}
return jsonArr.map(jsonObj => {
const localContext = jsonObj["@context"]
return mergeContext(localContext, context)

})
}


function conciseExpandedForm(expanded) {
function filterAttribute(attr) {
if (typeof(attr) === 'object') {
if ("@type" in attr && (attr["@type"][0] === 'https://uri.etsi.org/ngsi-ld/Property' ||
attr["@type"][0] === "https://uri.etsi.org/ngsi-ld/Relationship")) {
delete attr["@type"];
}
if ("https://uri.etsi.org/ngsi-ld/hasValue" in attr) {
attr["@value"] = attr["https://uri.etsi.org/ngsi-ld/hasValue"][0]["@value"]
delete attr["https://uri.etsi.org/ngsi-ld/hasValue"];
}
}
}
expanded.forEach(c => {
Object.keys(c).forEach(key => {
if (Array.isArray(c[key])) {
c[key].forEach(a => filterAttribute(a))
} else {
filterAttribute(c[key])
}
})
})
return expanded;
}


async function expand(objArr, contextArr) {
const expanded = await Promise.all(objArr.map(async(jsonObj, index) => {
jsonObj['@context'] = contextArr[index];
var res = await jsonld.expand(jsonObj)
return res[0];
}));
return expanded;
}


async function compact(objArr, contextArr) {
return await Promise.all(objArr.map(async(jsonObj, index) => jsonld.compact(jsonObj, contextArr[index])));
}


(async (jsonArr) => {
if (!(argv.n === undefined)) {
const mergedContexts = mergeContexts(jsonArr, argv.c);
if (mergedContexts !== undefined && mergedContexts.find(x => x === null)) {
console.error("Error: For Compaction, context must be either defined in all objects or externally. Exiting!");
process.exit(1);
}
const expanded = await jsonld.expand(jsonObj);
console.log(JSON.stringify(expanded, null, 2));
// Compaction to find Properties in compacted form
const expanded = await expand(jsonArr, mergedContexts);
const concised = conciseExpandedForm(expanded);
const compacted = await compact(concised, mergedContexts);
//const concisedAmdcompacted = await Promise.all(compacted.map(async(jsonObj, index) => jsonld.compact(jsonObj, mergedContexts[index])));
console.log(JSON.stringify(compacted, null, 2));

}

})(jsonFileName)
})(jsonArr)
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"dependencies": {
"ajv": "^8.12.0",
"json-schema-ref-parser": "^9.0.9",
"jsonld": "^8.3.1",
"jsonld-context-parser": "^2.3.3",
"n3": "^1.17.1",
"rdflib": "^2.2.32",
Expand Down
14 changes: 14 additions & 0 deletions tests/payload1.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"@context": "https://wagmarcel.github.io/json-schema-ngsild/schema-ngsild-eclass/context.jsonld",
"machine_state": "Testing",
"machine_state_from_smartbox": "Offline_Idle",
"hasFilter": {
"object": "urn:filter:1"
},
"testiri": {
"@id": "iffk:testiri"
},
"eclass:0173-1#02-AAH880#003": "10",
"id": "urn:x:1",
"type": "eclass:0173-1#01-AKJ975#017"
}
37 changes: 37 additions & 0 deletions tests/payload2.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"https://industry-fusion.org/eclass#0173-1#02-AAH880#003": [
{
"@value": "10"
}
],
"https://industry-fusion.org/base/v0.1/hasFilter": [
{
"https://uri.etsi.org/ngsi-ld/hasObject": [
{
"@id": "urn:filter:1"
}
]
}
],
"@id": "urn:x:1",
"https://industry-fusion.org/base/v0.1/machine_state": [
{
"@value": "Testing"
}
],
"https://industry-fusion.org/base/v0.1/machine_state_from_smartbox": [
{
"@value": "Offline_Idle"
}
],
"https://industry-fusion.org/base/v0.1/testiri": [
{
"@id": "https://industry-fusion.org/knowledge/v0.1/testiri"
}
],
"@type": [
"https://industry-fusion.org/knowledge/v0.1/0173-1#01-AKJ975#017"
]
}
]
18 changes: 18 additions & 0 deletions tests/payload3.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"@context": "https://wagmarcel.github.io/json-schema-ngsild/schema-ngsild-eclass/context.jsonld",
"machine_state": "Testing",
"machine_state_from_smartbox": "Offline_Idle",
"hasFilter": {
"type": "Relationship",
"object": "urn:filter:1"
},
"testiri": {
"@id": "iffk:testiri"
},
"eclass:0173-1#02-AAH880#003": {
"value": "10",
"type": "Property"
},
"id": "urn:x:1",
"type": "eclass:0173-1#01-AKJ975#017"
}

0 comments on commit faad3f6

Please sign in to comment.