- Purpose
- Prerequisites
- Installation
- Usage
- Development
- Design Choices and Known Limitations
- Markdown linter
-
Generate a template Excel workbook
in-shacl/template.xslx, a template schema JSON filein-shacl/template.schema.json, and 2 Excel workbooks with dummy datain-shacl/dummydata-a1.xslsandin-shacl/dummydata-a2.xslsbased on a SHACL shapes file inin-shacl/shacl.ttl. -
Convert the input data in
in/*.xlsxcombined with schema datain-shacl/template.schema.jsonto RDF output inout/serve-me/output.ttl.Note that user intervention is required to go from above-mentioned Excel workbooks with dummy data to real data in
in/*.xlsx. See Produce input data using the template Excel workbook and also Optionally include additional data below. -
Generate a list of prepared queries in one file
out/queries/generated-queries.rq. -
Split this one file into separate query files in dir
out/queries/generated-queries. -
Build a Miravi instance using the initial configuration in
miravi-initial-config, extended with queries for all the separated query files generated above, intonode_modules/miravi/main/dist.
Make sure you have installed:
- A platform with a bash shell
- Node >= 22 with npm
- Java version 17, e.g. 17.0.10-tem
-
Install dependencies via
npm i
-
Run setup via
npm run setup
To generate a template Excel workbook in-shacl/template.xslx,
a template schema JSON file in-shacl/template.schema.json and
2 Excel workbooks with dummy data in-shacl/dummydata-a1.xsls and in-shacl/dummydata-a2.xsls
based on a SHACL shapes file in in-shacl/shacl.ttl, execute the following steps:
-
Add a Turtle file with SHACL shapes called
shacl.ttlto the directoryin-shacl. You can use, for example, this SHACL file:curl -L "https://data.vlaanderen.be/doc/applicatieprofiel/leermiddelen/kandidaatstandaard/2025-08-01/shacl/leermiddelen-SHACL.ttl" -o in-shacl/shacl.ttl -
Generate the aforementioned files via
node src/shacl-to-template.js
This script converts a SHACL shapes file into:
- An Excel workbook (
in-shacl/template.xlsx) where:- Each NodeShape with at least one property becomes a worksheet.
- Each PropertyShape becomes a column in the corresponding worksheet.
- A template schema JSON file
in-shacl/template.schema.jsonto facilitate the automated generation of YARRRML mappings and SPARQL queries. - Two Excel workbooks with dummy data
in-shacl/dummydata-a1.xslsandin-shacl/dummydata-a2.xslsfor testing and as guidance for the end users.
The input SHACL file must include:
Per shacl:NodeShape:
rdfs:label– used as the worksheet nameshacl:targetClassshacl:property
Per shacl:PropertyShape:
rdfs:label– used as column headersshacl:path
Additionally, the script processes the following properties of a PropertyShape and adds them to the _schema sheet:
shacl:classshacl:datatypeshacl:minCountshacl:maxCount
If shacl:minCount >= 1,
the corresponding column header in the Excel sheet is bold and underlined,
indicating it is a required field.
The script records this information in template.schema.json sheet to facilitate
the automated generation of YARRRML mappings and SPARQL queries.
To produce input data:
- Copy and rename the generated
in-shacl/template.xlsxto a new working file and save it in thein-folder. - Fill in all relevant tabs with appropriate data entries.
- Per sheet columns with a bold and underlined header are required. Other columns are optional.
- When adding more than one value to a cell,
use
|as separator. - Ensure each row has a CODE (e.g. formatted as
<SheetName>_001,<SheetName>_002, etc.). - Pay special attention to foreign key columns: these must reference existing codes from the linked sheets
as defined under
valueForeignKeySheetintemplate.schema.json.
Maintaining consistent and valid codes ensures referential integrity across the dataset.
Several actors can add their own input data in the in-folder.
Note: When using a SHACL shape from an OSLO application profile as input, the diagram of that application profile visualizes the links between the sheets and mentions the expected datatype.
Note: Our tool ignores without header or with header starting with _. You can use those columns to added remarks.
If you want to include additional data, not defined in the SHACL template, you can add extra sheets and/or columns.
Each sheet must contain exactly one CODE column.
Example: an additional sheet with name Agent.
| CODE | name | knows | age |
|---|---|---|---|
| agent1 | Alice | agent2 | 25 |
| agent2 | Bob | agent3 | 30 |
You may specify a custom vocabulary per sheets and sheet/columns combination in the sheet labeled _customVoc:
sheetLabel: the label per sheet,sheetClass: the class per sheet,columnLabel: the label per column,columnProperty: the property per column,valueDatatype: the datatype per value in the column,valueClass: the class per value in the column.
Example: the _customVoc sheet.
| sheetLabel | sheetClass | columnLabel | columnProperty | valueDatatype | valueClass |
|---|---|---|---|---|---|
| Agent | http://xmlns.com/foaf/0.1/Agent | age | http://xmlns.com/foaf/0.1/age | http://www.w3.org/2001/XMLSchema#integer | |
| Agent | http://xmlns.com/foaf/0.1/Agent | knows | http://xmlns.com/foaf/0.1/knows | http://xmlns.com/foaf/0.1/Agent |
Our tool will map any additional sheets and columns without such specifications to
http://missing.example.com/ + sheetLabel or columnlabel.
Our tool will convert unspecified values to string literals.
With the above examples as input, our tool will map the column name to property http://missing.example.com/name,
and the values Alice and Bob to literals with datatype xsd:string.
The above examples result in the following additional RDF data:
@prefix ex: <http://example.com/> .
@prefix missing: <http://missing.example.com/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:agent1 a foaf:Agent;
missing:name "Alice":
foaf:knows ex:agent2;
foaf:age "25"^^^xsd:integer.
ex:agent2 a foaf:Agent;
missing:name "Bob":
foaf:knows ex:agent3;
foaf:age "30"^^^xsd:integer.
ex:agent3 a foaf:Agent. You may specify prefixes in the sheet labeled _prefixes, enabling the use of compact URIs in the sheet _customVoc.
Example: the _customVoc sheet with compact URIs.
| sheetLabel | sheetClass | columnLabel | columnProperty | valueDatatype | valueClass |
|---|---|---|---|---|---|
| Agent | foaf:Agent | age | foaf:age | xsd:integer | |
| Agent | foaf:Agent | knows | foaf:knows | foaf:Agent |
Example: the _prefixes sheet in the same data file.
| prefix | uri |
|---|---|
| foaf | http://xmlns.com/foaf/0.1/ |
| xsd | http://www.w3.org/2001/XMLSchema# |
If you leave sheetLabel and sheetClass empty,
the tool applies remaining specifications to any additional column with the corresponding column label as header.
Example: _customVoc sheet with column specifications that are reusable in any sheet.
| sheetLabel | sheetClass | columnLabel | columnProperty | valueDatatype | valueClass |
|---|---|---|---|---|---|
| age | foaf:age | xsd:integer | |||
| knows | foaf:knows | foaf:Agent |
The sheet labeled _customVoc in the generated template includes seven such column specifications by default.
Our tool ignores the additional sheets and columns when you select strict mode.
To process the input data in/*.xlsx as promised in purpose above, execute:
./run.sh -u '<the base URL where the RDF output files will be served (include trailing slash)>'
# example:
# ./run.sh -u 'https://www.example.com/'Add the option -s to process the input data in strict mode, ignoring custom vocabulary.
./run.sh -s -u '<the base URL where the RDF output files will be served (include trailing slash)>'If you want to add application-specific queries to the Miravi instance, proceed as follows:
- Extend the array
"queries"in miravi-initial-config/config.json. Note that you don't have to add a"comunicaContext":./run.shdoes that for you. - Add your corresponding SPARQL queries to miravi-initial-config/public/queries/.
- Re-run the
run.shcommand explained in above Process the input data section.
In miravi-initial-config/config.json, you can also adapt other settings such as titles, names, comments, images. You can find further information on Miravi configuration in this repository.
Our tool uses id gr-tooling-other and id gr-tooling-join to group generated queries, consequently you must not adapt those ids.
- Serve the RDF output in directory
out/serve-meat<base URL where the RDF output will be served>. - Serve the Miravi build result in
node_modules/miravi/main/distat a URL of your choice.
Execute:
./run.shIn a separate shell, host the RDF output on a web server:
npm run serveIn a separate shell, run the Miravi build result
npm run miraviVisit Miravi at http://localhost:5173.
Run:
npm test- OSLO SHACL shapes generated by Toolchain 4 should contain the expected information. Older OSLO SHACL shapes do not match the requirements.
- Information about subclasses and superclasses is not available in the SHACL shapes, and therefore not considered within this tool chain.
- NodeShapes with
skos:Conceptasshacl:targetClassare not converted to sheets intemplate.xlsx. As there is no one-on-one relation between a label and an iri, this leads to strange query results. - All values with datatype
rdf:langStringare converted to RDF with language code@nl. - Adding more than one data EXCEL file to the
in-folder may impact the query processing time as the default queries contain severalOPTIONALs. - The last row per sheet of the generated dummy data contains multiple values per cell
when the
maxCountfor that property in the SHACL shape is not equal to 1.
You can run the Markdown linter via
npm run lint:markdownIf you want the tool to automatically try to fix issues, execute
npm run lint:markdown:fix