@igea/oac_backend 1.0.38 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/controllers/fuseki.js +115 -1
- package/src/controllers/ontology.js +77 -2
- package/src/models/{Converter → converter.js} +37 -0
- package/src/models/fuseki.js +22 -0
- package/src/ontology/schema_v2.shacl.ttl +24 -50
- package/test/models/converter.test.js +30 -0
- package/test/models/example-01.ttl +46 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igea/oac_backend",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.40",
|
|
4
4
|
"description": "Backend service for the OAC project",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"n3": "1.26.0",
|
|
37
37
|
"nodemailer": "7.0.6",
|
|
38
38
|
"pg": "8.16.3",
|
|
39
|
-
"strip-bom": "5.0.0"
|
|
39
|
+
"strip-bom": "5.0.0",
|
|
40
|
+
"tmp": "0.2.5"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"chai": "5.2.1",
|
|
@@ -116,6 +116,121 @@ router.post('/upload/vocabularies', upload.array('files'), (req, res) => {
|
|
|
116
116
|
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
+
//---------------------------------------------------------------
|
|
120
|
+
router.get('/get-vocabolary-terms/:key', (req, res) => {
|
|
121
|
+
const key = req.params.key;
|
|
122
|
+
const rootIRI = `<http://diagnostica/vocabularies/${key}>`;
|
|
123
|
+
|
|
124
|
+
let _query = `PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
|
|
125
|
+
CONSTRUCT {
|
|
126
|
+
?concept ?p ?o .
|
|
127
|
+
}
|
|
128
|
+
WHERE {
|
|
129
|
+
?concept (crm:P127_has_broader_term*) ${rootIRI} .
|
|
130
|
+
?concept ?p ?o .
|
|
131
|
+
}`;
|
|
132
|
+
|
|
133
|
+
let query = `PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
|
|
134
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
135
|
+
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
|
|
136
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
137
|
+
|
|
138
|
+
CONSTRUCT {
|
|
139
|
+
|
|
140
|
+
?concept a owl:Class ;
|
|
141
|
+
rdfs:subClassOf ?parent ;
|
|
142
|
+
skos:prefLabel ?label ;
|
|
143
|
+
skos:closeMatch ?mappedConcept .
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
WHERE {
|
|
147
|
+
|
|
148
|
+
# Trovo tutti i concetti del vocabolario
|
|
149
|
+
?concept (crm:P127_has_broader_term*) ${rootIRI} .
|
|
150
|
+
|
|
151
|
+
# Recupero l'etichetta
|
|
152
|
+
OPTIONAL { ?concept rdfs:label ?label . }
|
|
153
|
+
|
|
154
|
+
# Prelevo il parent da broader term
|
|
155
|
+
OPTIONAL {
|
|
156
|
+
?concept crm:P127_has_broader_term ?parent .
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Genero un mapping verso un URI esterno
|
|
160
|
+
BIND(
|
|
161
|
+
IRI(CONCAT("${rootIRI}", REPLACE(STR(?concept), "^.*[/#]", "")))
|
|
162
|
+
AS ?mappedConcept
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
ORDER BY ?label`
|
|
167
|
+
|
|
168
|
+
axios.post(fusekiUrl, `query=${encodeURIComponent(query)}`,{
|
|
169
|
+
headers: {
|
|
170
|
+
'Accept': `text/turtle`,
|
|
171
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
172
|
+
},
|
|
173
|
+
responseType: 'stream'
|
|
174
|
+
}).then(response => {
|
|
175
|
+
res.setHeader('Content-Type', response.headers['content-type']);
|
|
176
|
+
response.data.pipe(res);
|
|
177
|
+
}).catch(err => {
|
|
178
|
+
res.status(500).json({
|
|
179
|
+
success: false,
|
|
180
|
+
data: null,
|
|
181
|
+
message: `Error: ${err}`
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
})
|
|
185
|
+
//---------------------------------------------------------------
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
189
|
+
|
|
190
|
+
SELECT ?obj
|
|
191
|
+
WHERE {
|
|
192
|
+
?obj rdf:type <http://www.cidoc-crm.org/cidoc-crm/E55_Type> .
|
|
193
|
+
}
|
|
194
|
+
ORDER BY ?obj
|
|
195
|
+
LIMIT 10
|
|
196
|
+
OFFSET 50
|
|
197
|
+
*/
|
|
198
|
+
//---------------------------------------------------------------
|
|
199
|
+
router.post('/search/by-prefix', (req, res) => {
|
|
200
|
+
const query = Fuseki.getQuerySearchByPrefix(
|
|
201
|
+
req.body.prefix || "",
|
|
202
|
+
parseInt(req.body.limit) || 50,
|
|
203
|
+
parseInt(req.body.offset) || 0
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
axios.post(fusekiUrl, `query=${encodeURIComponent(query)}`, {
|
|
207
|
+
headers: {
|
|
208
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
209
|
+
'Accept': 'application/sparql-results+json'
|
|
210
|
+
}
|
|
211
|
+
}).then(response => {
|
|
212
|
+
const bindings = response.data.results.bindings;
|
|
213
|
+
let results = []
|
|
214
|
+
bindings.forEach(result => {
|
|
215
|
+
results.push({
|
|
216
|
+
instance: result.instance.value,
|
|
217
|
+
label: result.label.value,
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
res.json({
|
|
221
|
+
success: true,
|
|
222
|
+
data: results,
|
|
223
|
+
message: null
|
|
224
|
+
});
|
|
225
|
+
}).catch(err => {
|
|
226
|
+
res.status(500).json({
|
|
227
|
+
success: false,
|
|
228
|
+
data: null,
|
|
229
|
+
message: `Error: ${err}`
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
});
|
|
119
234
|
//---------------------------------------------------------------
|
|
120
235
|
router.get('/count/entities', (req, res) => {
|
|
121
236
|
const query = `
|
|
@@ -154,7 +269,6 @@ router.get('/count/entities', (req, res) => {
|
|
|
154
269
|
message: `Error: ${err}`
|
|
155
270
|
});
|
|
156
271
|
});
|
|
157
|
-
|
|
158
272
|
});
|
|
159
273
|
|
|
160
274
|
router.get('/export/:format/:entity/:id', (req, res) => {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const router = express.Router();
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const ONTO_FOLDER = path.join(__dirname, '..', 'ontology');
|
|
6
|
+
const Converter = require('../models/converter');
|
|
7
|
+
const tmp = require('tmp');
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
router.get('/schema/:format', (req, res) => {
|
|
7
11
|
console.log(`Requesting SHACL schema in format: ${req.params.format}`);
|
|
@@ -32,7 +36,20 @@ router.get('/schema/:format', (req, res) => {
|
|
|
32
36
|
});
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
35
|
-
|
|
39
|
+
|
|
40
|
+
let fileContent = fs.readFileSync(path.join(ONTO_FOLDER, filePath), 'utf8');
|
|
41
|
+
let protocol = process.env.OAC_EXPOSED_PROTOCOL || 'http';
|
|
42
|
+
let host = process.env.OAC_EXPOSED_HOST || '127.0.0.1';
|
|
43
|
+
if(host=="localhost") host="127.0.0.1";
|
|
44
|
+
let port = process.env.OAC_EXPOSED_PORT || '4000';
|
|
45
|
+
fileContent = fileContent.replace(/OAC_EXPOSED_PROTOCOL/g, protocol);
|
|
46
|
+
fileContent = fileContent.replace(/OAC_EXPOSED_HOST/g, host);
|
|
47
|
+
fileContent = fileContent.replace(/OAC_EXPOSED_PORT/g, port);
|
|
48
|
+
|
|
49
|
+
const tempFile = tmp.fileSync({ postfix: filePath });
|
|
50
|
+
fs.writeFileSync(tempFile.name, fileContent);
|
|
51
|
+
|
|
52
|
+
res.sendFile(tempFile.name, (err) => {
|
|
36
53
|
if (err) {
|
|
37
54
|
res.status(500).json({
|
|
38
55
|
success: false,
|
|
@@ -93,5 +110,63 @@ router.get('/schema-temp', (req, res) => {
|
|
|
93
110
|
});
|
|
94
111
|
});
|
|
95
112
|
|
|
113
|
+
router.post('/convert/:from/:to', (req, res) => {
|
|
114
|
+
const from = req.params.from;
|
|
115
|
+
const to = req.params.to;
|
|
116
|
+
console.log(`Requesting conversion from ${from} to ${to}`);
|
|
117
|
+
let conversionFunction = null
|
|
118
|
+
if(from === 'ttl' && to === 'xml'){
|
|
119
|
+
conversionFunction = Converter.turtle2RdfXml
|
|
120
|
+
}else if(from === 'xml' && to === 'ttl'){
|
|
121
|
+
conversionFunction = Converter.rdfXml2Turtle
|
|
122
|
+
}else{
|
|
123
|
+
res.status(400).json({
|
|
124
|
+
success: false,
|
|
125
|
+
data: null,
|
|
126
|
+
message: `Unsupported conversion from ${from} to ${to}`
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const inputFile = tmp.fileSync({ postfix: `.${from}` });
|
|
132
|
+
const outputFile = tmp.fileSync({ postfix: `.${to}` });
|
|
133
|
+
|
|
134
|
+
const content = req.body.file
|
|
135
|
+
|
|
136
|
+
fs.writeFileSync(inputFile, content);
|
|
137
|
+
|
|
138
|
+
const removeFiles = function(_files){
|
|
139
|
+
for(let i=0; i<_files.length; i++){
|
|
140
|
+
try {
|
|
141
|
+
fs.unlinkSync(_files[i]);
|
|
142
|
+
console.log(`File ${_files[i]} removed`);
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.error(`Error deleting ${_files[i]}`, e);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
let files = [inputFile];
|
|
149
|
+
conversionFunction(inputFile, outputFile).then(() => {
|
|
150
|
+
res.sendFile(outputFile, (err) => {
|
|
151
|
+
if (err) {
|
|
152
|
+
res.status(500).json({
|
|
153
|
+
success: false,
|
|
154
|
+
data: null,
|
|
155
|
+
message: `Error sending file: ${err}`
|
|
156
|
+
});
|
|
157
|
+
files = [inputFile]
|
|
158
|
+
}
|
|
159
|
+
files.push(outputFile)
|
|
160
|
+
removeFiles(files)
|
|
161
|
+
});
|
|
162
|
+
}).catch(err => {
|
|
163
|
+
res.status(500).json({
|
|
164
|
+
success: false,
|
|
165
|
+
data: null,
|
|
166
|
+
message: `Conversion error: ${err}`
|
|
167
|
+
});
|
|
168
|
+
removeFiles(files)
|
|
169
|
+
});
|
|
170
|
+
})
|
|
96
171
|
|
|
97
172
|
module.exports = router
|
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { Parser } = require('n3');
|
|
3
3
|
const { DataFactory, Store } = require('n3');
|
|
4
|
+
const { exec } = require('child_process');
|
|
4
5
|
|
|
5
6
|
class Converter {
|
|
6
7
|
|
|
8
|
+
static async turtle2RdfXml(inTurtlePath, outRdfXmlPath) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const command = `rapper -i turtle -o rdfxml "${inTurtlePath}" > "${outRdfXmlPath}"`;
|
|
11
|
+
exec(command, (error, stdout, stderr) => {
|
|
12
|
+
if (error) {
|
|
13
|
+
console.error(`Error during conversion: ${error.message}`);
|
|
14
|
+
reject(error);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (stderr) {
|
|
18
|
+
console.log(`Conversion stderr: ${stderr}`);
|
|
19
|
+
}
|
|
20
|
+
console.log(`Conversion stdout: ${stdout}`);
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static async rdfXml2Turtle(inRdfXmlPath, outTurtlePath) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const command = `rapper -i rdfxml -o turtle "${inRdfXmlPath}" > "${outTurtlePath}"`;
|
|
29
|
+
exec(command, (error, stdout, stderr) => {
|
|
30
|
+
if (error) {
|
|
31
|
+
console.error(`Error during conversion: ${error.message}`);
|
|
32
|
+
reject(error);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (stderr) {
|
|
36
|
+
console.log(`Conversion stderr: ${stderr}`);
|
|
37
|
+
}
|
|
38
|
+
console.log(`Conversion stdout: ${stdout}`);
|
|
39
|
+
resolve();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
7
44
|
// Funzione per generare messaggi di errore multilingua
|
|
8
45
|
static generateErrorMessages(propertyName, datatype, isRelation) {
|
|
9
46
|
const messages = {
|
package/src/models/fuseki.js
CHANGED
|
@@ -84,6 +84,28 @@ class Fuseki {
|
|
|
84
84
|
}`;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
static getQuerySearchByPrefix(prefix, limit, offset){
|
|
88
|
+
limit = limit || 50;
|
|
89
|
+
offset = offset || 0;
|
|
90
|
+
if(limit < 1) limit = 50;
|
|
91
|
+
return `
|
|
92
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
93
|
+
SELECT DISTINCT ?instance ?label
|
|
94
|
+
WHERE {
|
|
95
|
+
# tutte le istanze con qualsiasi proprietà
|
|
96
|
+
?instance ?p ?o .
|
|
97
|
+
# filtro per IRI che inizia con il prefisso specifico
|
|
98
|
+
FILTER(STRSTARTS(STR(?instance), "${prefix}"))
|
|
99
|
+
# filtro per IRI che termina con UUID
|
|
100
|
+
#FILTER(REGEX(STR(?instance), "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"))
|
|
101
|
+
# label opzionale
|
|
102
|
+
OPTIONAL { ?instance rdfs:label ?label . }
|
|
103
|
+
}
|
|
104
|
+
ORDER BY ?label
|
|
105
|
+
LIMIT ${limit}
|
|
106
|
+
OFFSET ${offset}`
|
|
107
|
+
}
|
|
108
|
+
|
|
87
109
|
}
|
|
88
110
|
|
|
89
111
|
module.exports = Fuseki;
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
4
4
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
5
5
|
@prefix crm: <http://www.cidoc-crm.org/cidoc-crm/> .
|
|
6
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
7
|
+
@prefix dcterms: <http://purl.org/dc/terms/> .
|
|
6
8
|
|
|
7
9
|
ex:E7ActivityShape
|
|
8
10
|
a sh:NodeShape ;
|
|
@@ -57,7 +59,8 @@ ex:E42IdentifierShape
|
|
|
57
59
|
sh:path ex:P48_has_preferred_identifier ;
|
|
58
60
|
sh:datatype xsd:string ;
|
|
59
61
|
sh:name "ID" ;
|
|
60
|
-
|
|
62
|
+
sh:nodeKind sh:IRI;
|
|
63
|
+
sh:description "http://diagnostica/indagine/$UUID$" ;
|
|
61
64
|
sh:maxCount 1 ;
|
|
62
65
|
sh:minCount 1 ;
|
|
63
66
|
] .
|
|
@@ -66,24 +69,14 @@ ex:E55Type01Shape
|
|
|
66
69
|
a sh:NodeShape ;
|
|
67
70
|
sh:targetClass crm:E55_Type ;
|
|
68
71
|
sh:property [
|
|
69
|
-
sh:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
sh:in ( "Tipo indagine A" "Tipo indagine B" ) ;
|
|
73
|
-
#owl:imports
|
|
72
|
+
sh:class owl:Class ;
|
|
73
|
+
sh:path crm:P127_has_broader_term ;
|
|
74
|
+
owl:imports <OAC_EXPOSED_PROTOCOL://OAC_EXPOSED_HOST:OAC_EXPOSED_PORT/backend/fuseki/get-vocabolary-terms/fase-di-analisi> ;
|
|
74
75
|
sh:name "Tipo" ;
|
|
75
76
|
sh:maxCount 1 ;
|
|
76
77
|
sh:minCount 1 ;
|
|
77
78
|
] .
|
|
78
79
|
|
|
79
|
-
# Vocabolario E55Type01 (Tipo indagine)
|
|
80
|
-
#ex:TipoIndagineA
|
|
81
|
-
# a crm:E55_Type ;
|
|
82
|
-
# rdfs:label "Tipo indagine A" .
|
|
83
|
-
#ex:TipoIndagineB
|
|
84
|
-
# a crm:E55_Type ;
|
|
85
|
-
# rdfs:label "Tipo indagine B" .
|
|
86
|
-
|
|
87
80
|
ex:I12AdoptedBeliefShape
|
|
88
81
|
a sh:NodeShape ;
|
|
89
82
|
sh:targetClass crm:I12_Adopted_Belief ;
|
|
@@ -99,13 +92,18 @@ ex:E55Type02Shape
|
|
|
99
92
|
a sh:NodeShape ;
|
|
100
93
|
sh:targetClass crm:E55_Type ;
|
|
101
94
|
sh:property [
|
|
102
|
-
sh:path ex:P2hastype2 ;
|
|
103
|
-
#sh:class ex:E55Type02 ;
|
|
104
|
-
#sh:in ( ex:TipoQuesitoDiagnostico1 ex:TipoQuesitoDiagnostico2 ex:TipoQuesitoDiagnostico3 ) ;
|
|
105
|
-
sh:in ( "Tipo quesito diagnistico 1" "Tipo quesito diagnistico 2" "Tipo quesito diagnistico 3" ) ;
|
|
106
95
|
sh:name "Tipo" ;
|
|
107
96
|
sh:maxCount 1 ;
|
|
108
97
|
sh:minCount 1 ;
|
|
98
|
+
#sh:class crm:E55_Type ;
|
|
99
|
+
sh:class owl:Class ;
|
|
100
|
+
sh:path crm:P127_has_broader_term ;
|
|
101
|
+
owl:imports <OAC_EXPOSED_PROTOCOL://OAC_EXPOSED_HOST:OAC_EXPOSED_PORT/backend/fuseki/get-vocabolary-terms/quesito-diagnostico> ;
|
|
102
|
+
|
|
103
|
+
#sh:class owl:Class ;
|
|
104
|
+
#sh:path dcterms:subject ;
|
|
105
|
+
#owl:imports <https://raw.githubusercontent.com/tibonto/DFG-Fachsystematik-Ontology/refs/heads/main/dfgfo.ttl> ;
|
|
106
|
+
|
|
109
107
|
] ;
|
|
110
108
|
sh:property [
|
|
111
109
|
sh:path crm:P3_has_note ;
|
|
@@ -114,25 +112,20 @@ ex:E55Type02Shape
|
|
|
114
112
|
sh:maxCount 1 ;
|
|
115
113
|
] .
|
|
116
114
|
|
|
117
|
-
# Vocabolario E55Type02 (Tipo quesito diagnostico)
|
|
118
|
-
#ex:TipoQuesitoDiagnostico1
|
|
119
|
-
# a crm:E55_Type ;
|
|
120
|
-
# rdfs:label "Tipo quesito diagnistico 1" .
|
|
121
|
-
#ex:TipoQuesitoDiagnostico2
|
|
122
|
-
# a crm:E55_Type ;
|
|
123
|
-
# rdfs:label "Tipo quesito diagnistico 2" .
|
|
124
|
-
#ex:TipoQuesitoDiagnostico3
|
|
125
|
-
# a crm:E55_Type ;
|
|
126
|
-
# rdfs:label "Tipo quesito diagnistico 3" .
|
|
127
|
-
|
|
128
115
|
ex:E29ActorShape
|
|
129
116
|
a sh:NodeShape ;
|
|
130
117
|
sh:targetClass crm:E29_Actor ;
|
|
131
118
|
sh:property [
|
|
132
119
|
sh:path ex:ente_richiedente ;
|
|
133
120
|
sh:datatype xsd:string ;
|
|
134
|
-
|
|
135
|
-
sh:
|
|
121
|
+
|
|
122
|
+
#sh:name "Ente richiedente" ;
|
|
123
|
+
#sh:maxCount 1 ;
|
|
124
|
+
|
|
125
|
+
sh:name "ID" ;
|
|
126
|
+
sh:nodeKind sh:IRI;
|
|
127
|
+
sh:description "http://diagnostica/actor/$UUID$" ;
|
|
128
|
+
|
|
136
129
|
] ;
|
|
137
130
|
sh:property [
|
|
138
131
|
sh:path ex:schedatore ;
|
|
@@ -141,22 +134,3 @@ ex:E29ActorShape
|
|
|
141
134
|
sh:maxCount 1 ;
|
|
142
135
|
sh:minCount 1 ;
|
|
143
136
|
] .
|
|
144
|
-
|
|
145
|
-
#Vocabolario E55Type03a (con unico termine "Ente_richiedente") ???
|
|
146
|
-
#Vocabolario E55Type03b (con unico termine "Ente_schedatore") ???
|
|
147
|
-
#ex:TipoAttore1
|
|
148
|
-
# a crm:E55_Type ;
|
|
149
|
-
# rdfs:label "Ente richiedente" .
|
|
150
|
-
#ex:TipoAttore2
|
|
151
|
-
# a crm:E55_Type ;
|
|
152
|
-
# rdfs:label "Schedatore" .
|
|
153
|
-
|
|
154
|
-
#ex:E55Type03Shape
|
|
155
|
-
# a sh:NodeShape ;
|
|
156
|
-
# sh:targetClass crm:E55_Type ;
|
|
157
|
-
# sh:property [
|
|
158
|
-
# sh:path crm:P1_is_defined_by ;
|
|
159
|
-
# sh:node ex:E41AppellationShape ;
|
|
160
|
-
# sh:name "Attore" ;
|
|
161
|
-
# sh:maxCount 1 ;
|
|
162
|
-
# ] .
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const chai = require('chai');
|
|
2
|
+
const expect = chai.expect;
|
|
3
|
+
const request = require('supertest');
|
|
4
|
+
const converter = require('../../src/models/converter');
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
|
|
7
|
+
describe('Converter', () => {
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should convert a turtle file to a rdf/xml', (done) => {
|
|
14
|
+
let inputTurtle = __dirname + '/example-01.ttl';
|
|
15
|
+
let outputRdfXml = __dirname + '/example-01.xml';
|
|
16
|
+
converter.turtle2RdfXml(inputTurtle, outputRdfXml).then(() => {
|
|
17
|
+
let isOk = fs.existsSync(outputRdfXml)
|
|
18
|
+
expect(isOk).to.be.equal(true);
|
|
19
|
+
if(isOk) {
|
|
20
|
+
console.log('Removing temp file: ' + outputRdfXml);
|
|
21
|
+
fs.unlinkSync(outputRdfXml);
|
|
22
|
+
}
|
|
23
|
+
done()
|
|
24
|
+
}).catch(err => {
|
|
25
|
+
console.error(err);
|
|
26
|
+
done();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
2
|
+
@prefix schema: <http://schema.org/> .
|
|
3
|
+
@prefix dcterms: <http://purl.org/dc/terms/> .
|
|
4
|
+
@prefix dcat: <http://www.w3.org/ns/dcat#> .
|
|
5
|
+
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
|
|
6
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
7
|
+
@prefix example: <http://example.org/> .
|
|
8
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
|
9
|
+
@prefix prov: <http://www.w3.org/ns/prov#> .
|
|
10
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
11
|
+
|
|
12
|
+
example:4f2a8de3-9fc8-40a9-9237-d5964520ec54
|
|
13
|
+
a dcat:Dataset, example:ArchitectureModelDataset ;
|
|
14
|
+
dcterms:title "Einsteinturm"@de, "Einstein Tower"@en ;
|
|
15
|
+
dcterms:description "Modell des Einsteinturms"@de, "Model of the Einstein Tower"@en ;
|
|
16
|
+
dcterms:issued "2023-07-27"^^xsd:date ;
|
|
17
|
+
dcterms:subject <https://w3id.org/dfgfo/2024/451-01>;
|
|
18
|
+
dcterms:license <http://creativecommons.org/licenses/by/4.0/> ;
|
|
19
|
+
schema:artworkSurface example:plaster ;
|
|
20
|
+
schema:width 200 ;
|
|
21
|
+
dcterms:spatial [
|
|
22
|
+
a dcterms:Location ;
|
|
23
|
+
geo:asWKT "POLYGON((13.06382134836241 52.37900504575066,13.063796707503286 52.37896794299019,13.063798350228126 52.37875635638159,13.063926482692182 52.37875435081642,13.0639281254158 52.378964934657034,13.063905127281544 52.37900404297392,13.06382134836241 52.37900504575066))"^^geo:wktLiteral ;
|
|
24
|
+
dcterms:description "Building has been realized here" ;
|
|
25
|
+
] ;
|
|
26
|
+
dcterms:spatial [
|
|
27
|
+
a dcterms:Location ;
|
|
28
|
+
geo:asWKT "POINT(8.681927539753275 50.09895428462539)"^^geo:wktLiteral ;
|
|
29
|
+
dcterms:description "Model is stored here" ;
|
|
30
|
+
] ;
|
|
31
|
+
prov:qualifiedAttribution [
|
|
32
|
+
a prov:Attribution ;
|
|
33
|
+
prov:agent [
|
|
34
|
+
a foaf:Person ;
|
|
35
|
+
foaf:name "Jane Doe";
|
|
36
|
+
dcterms:identifier "https://orcid.org/0000-0002-1584-4316" ;
|
|
37
|
+
] ;
|
|
38
|
+
dcat:hadRole <http://w3id.org/nfdi4ing/metadata4ing#Researcher> ;
|
|
39
|
+
] .
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
example:darmstadt
|
|
43
|
+
a dcterms:Location ;
|
|
44
|
+
rdfs:label "Darmstadt" ;
|
|
45
|
+
geo:asWKT "POINT(8.657631022574474 49.87622847744955)"^^geo:wktLiteral ;
|
|
46
|
+
dcterms:description "Darmstadt is a city in germany" .
|