railML® to ERA Ontology Conversion

February 22, 2026 · View on GitHub

Overview

Pipeline for converting railML 3.2 infrastructure data to the ERA ontology (RINF-compatible RDF).

⚠️ Built around the advanced example v14 of railML® in preparation for a Workshop at ERA. Scripts are reusable but assumptions are hardcoded — use with caution for other inputs.

⚠️ The advanced-example.xml source file is not included due to railML® licensing. See 01-prep/README.md.

Pipeline

railML XML
  ↓ [01-prep]         SPARQL Anything → one-eyed-graph.ttl
  ↓ [02-construct]    SPARQL CONSTRUCT → era-graph.ttl
  ↓ [03-post-process] Geometry enrichment → era-graph-enriched.ttl
  ↓ [04-validate]     SHACL validation → validation-report.ttl
  ↓ [upload-to-rinf]  Upload to https://jena.matdata.eu/rinf

A separate standalone script in 06-create-topology builds ERA topology from Belgian open rail segment data (Infrabel).

Steps

StepFolderPurposeOutput
101-prepConvert railML XML → raw RDF via SPARQL Anythingone-eyed-graph.ttl
202-constructSPARQL CONSTRUCT queries → ERA ontologyera-graph.ttl
303-post-processGeometry enrichment, data fixesera-graph-enriched.ttl
404-validateSHACL validation against ERA shapes (requires maplib license)validation-report.ttl
505-shacl-shaclValidate the SHACL shapes themselves—
606-create-topologyBuild ERA topology from Infrabel open datatopology.ttl

Quick Start

Prerequisites

  • Docker (for SPARQL Anything in step 1)
  • Python 3.10+ with virtual environment
  • Apache Jena Fuseki (optional, recommended)
pip install -r requirements.txt

Run

cd 01-prep        ; .\run-prep.ps1
cd ..\02-construct; .\run-construct.ps1
cd ..\03-post-process; .\run-post-process.ps1
cd ..\04-validate ; python validate.py

To upload to the remote Fuseki instance:

.\upload-to-rinf.ps1

Fuseki Integration

Steps 01–03 read/write named graphs in a local Fuseki instance and fall back to local files when unavailable.

StepDataset
01advanced-example-one-eyed/
02reads one-eyed/, writes advanced-example/
03updates advanced-example/