RO-Crate Schema Plus

Same RO-Crate

+ Convention for interoperable schema and metadata.

+ Convention to include interoperable schema and metadata outside ro-crate-metadata.json.

Use Cases

  1. Exchanging metadata between systems using a common format (RO-Crate) but also a fully defined schema (Interoperability Profile)
  2. Validation of imported metadata thanks to the well defined schema (Interoperability Profile)
  3. Go beyond using the ro-crate-metadata.json to include metadata, to support large exports. (Extensibility Profile)

Profile Specifications

Profile Status Version Comments
Interoperability Profile Release 0.2
Extensibility Profile Draft 0.1

API Specifications

Profile Status Version Comments
Client API Release 0.2 Read/write RO-crates containing schema and metadata
Server API Draft 1.0 Exports/imports RO-crates containing schema and metadata

Libraries

Language Status Interoperability Profile Extensibility Profile Comments
Java Release Candidate 0.2 Reference implementation
Python Active Development

Application Support

Application Status Interoperability Profile Extensibility Profile Comments
openBIS Active Development 0.2
SciCat Active Development 0.2
SciLog Active Development 0.2
AiiDAlab Planned

Quick Start Guide (Java)

In this example, we express two SQL tables in RO-Crate. It expresses experiments and each experiment can have a creator, who is a person.

SQL example source

CREATE TABLE person( -- https://schema.org/Person
    personid VARCHAR(255), 
    givenname VARCHAR(255), -- https://schema.org/givenName
    familyname VARCHAR(255), -- https://schema.org/familyName
    identifier VARCHAR (255), -- https://schema.org/identifier
    PRIMARY KEY(personid)


);

CREATE TABLE experiment(
    experimentid VARCHAR(255), 
    date DATETIME,
    name VARCHAR(255),
    creatorid VARCHAR(255), https://schema.org/creator
    PRIMARY_KEY(experimentid),
    FOREIGN KEY(creatorid) REFERENCES person(personid)
);

INSERT INTO PERSON (person_id, givenname, familyname, identifier) VALUES ('PERSON1', 'Meier', 'Andreas', 'https://orcid.org/0009-0002-6541-4637');
INSERT INTO PERSON (person_id, givenname, familyname, identifier) VALUES ('PERSON2', 'Fuentes', 'Juan', 'https://orcid.org/0009-0002-8209-1999');


INSERT INTO experiment (experimentid, date, name, creatorid) VALUES ('EXPERIMENT1', '2025-09-08 08:41:50', 'Example Experiment', 'Person1');



Tables are Types in our nomenclature, e.g.

IType personType = new Type()
Columns are PropertyTypes, e.g.
IPropertyType name = new PropertyType()
Both Types and PropertyTypes can be annotated to specify semantics. The rows are represented by IMetaDataEntry, their IType is specifed in the crate.

Write Ro-Crate Example

Java example source


import ch.eth.sis.rocrate.SchemaFacade;
import ch.eth.sis.rocrate.facade.*;
import edu.kit.datamanager.ro_crate.writer.FolderWriter;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class QuickStartWrite
{

    private static final String PREFIX = "Example";

    private static final String SEPARATOR = ":";

    public static final String TMP_EXAMPLE_CRATE = "/tmp/example-crate";

    public static void main(String[] args)
    {
        /* Setting up an RO-Crate with the schema facade */
        ISchemaFacade schemaFacade =
                new SchemaFacade("name", "description", "2024-12-04T07:53:11Z", "licenceIdentifier",
                        Map.of());

        Type personType = new Type();

        {
            personType.setId(PREFIX + SEPARATOR + "Person");
            personType.setOntologicalAnnotations(List.of("https://schema.org/Person"));

            {
                PropertyType personId = new PropertyType();
                personId.setId(PREFIX + SEPARATOR + "personid");
                personId.setTypes(List.of(LiteralType.STRING));
                personType.addProperty(personId);
            }
            {
                PropertyType givenName = new PropertyType();
                givenName.setId(PREFIX + SEPARATOR + "givenName");
                givenName.setOntologicalAnnotations(List.of("https://schema.org/givenName"));
                givenName.setTypes(List.of(LiteralType.STRING));
                personType.addProperty(givenName);
            }
            {
                PropertyType givenName = new PropertyType();
                givenName.setId(PREFIX + SEPARATOR + "familyName");
                givenName.setOntologicalAnnotations(List.of("https://schema.org/familyName"));
                givenName.setTypes(List.of(LiteralType.STRING));
                personType.addProperty(givenName);
            }
            {
                PropertyType identifier = new PropertyType();
                identifier.setId(PREFIX + SEPARATOR + "identifier");
                identifier.setOntologicalAnnotations(List.of("https://schema.org/identifier"));
                identifier.setTypes(List.of(LiteralType.STRING));
                personType.addProperty(identifier);
            }
            schemaFacade.addType(personType);

        }

        Type experimentType = new Type();

        /* Building our Experiment type */
        {
            experimentType.setId(PREFIX + SEPARATOR + "Experiment");

            {
                PropertyType experimentId = new PropertyType();
                experimentId.setId(PREFIX + SEPARATOR + "experimentid");
                experimentId.setTypes(List.of(LiteralType.STRING));
                experimentType.addProperty(experimentId);
            }
            {
                PropertyType creator = new PropertyType();
                creator.setId(PREFIX + SEPARATOR + "creator");
                creator.setOntologicalAnnotations(List.of("https://schema.org/creator"));
                creator.addType(personType);
                experimentType.addProperty(creator);
            }
            {
                PropertyType name = new PropertyType();
                name.setId(PREFIX + SEPARATOR + "name");
                name.setTypes(List.of(LiteralType.STRING));
                experimentType.addProperty(name);
            }
            {
                PropertyType date = new PropertyType();
                date.setId(PREFIX + SEPARATOR + "date");
                date.setTypes(List.of(LiteralType.DATETIME));
                experimentType.addProperty(date);
            }
            schemaFacade.addType(experimentType);

        }

        {
            MetadataEntry personAndreas = new MetadataEntry();
            personAndreas.setId("PERSON1");
            Map properties = new LinkedHashMap<>();
            personAndreas.setTypes(Set.of(personType.getId()));
            properties.put("givenname", "Andreas");
            properties.put("lastname", "Meier");
            properties.put("identifier", "https://orcid.org/0009-0002-6541-4637");
            personAndreas.setProps(properties);
            personAndreas.setReferences(new LinkedHashMap<>());
            schemaFacade.addEntry(personAndreas);

            MetadataEntry personJuan = new MetadataEntry();
            personJuan.setId("PERSON2");
            personJuan.setTypes(Set.of(personType.getId()));
            Map properties2 = new LinkedHashMap<>();
            properties2.put("givenname", "Andreas");
            properties2.put("lastname", "Meier");
            properties2.put("identifier", "https://orcid.org/0009-0002-6541-4637");
            personJuan.setProps(properties2);
            personJuan.setReferences(new LinkedHashMap<>());

            schemaFacade.addEntry(personJuan);

            MetadataEntry experiment1 = new MetadataEntry();
            experiment1.setId("EXPERIMENT1");
            experiment1.setReferences(Map.of("creator", List.of(personAndreas.getId())));
            experiment1.setTypes(Set.of(experimentType.getId()));
            Map propertiesExperiment = new LinkedHashMap<>();
            propertiesExperiment.put("name", "Example Experiment");
            propertiesExperiment.put("date", "2025-09-08 08:41:50.000");
            experiment1.setProps(propertiesExperiment);
            schemaFacade.addEntry(experiment1);

        }

        FolderWriter folderWriter = new FolderWriter();
        folderWriter.save(schemaFacade.getCrate(), TMP_EXAMPLE_CRATE);

    }

}


Read RO-Crate Example

Java example source

import ch.eth.sis.rocrate.SchemaFacade;
import ch.eth.sis.rocrate.facade.IMetadataEntry;
import ch.eth.sis.rocrate.facade.IPropertyType;
import ch.eth.sis.rocrate.facade.IType;
import com.fasterxml.jackson.core.JsonProcessingException;
import edu.kit.datamanager.ro_crate.RoCrate;
import edu.kit.datamanager.ro_crate.reader.FolderReader;
import edu.kit.datamanager.ro_crate.reader.RoCrateReader;

import java.util.List;

public class QuickStartRead
{

    public static void main(String[] args) throws JsonProcessingException
    {
        RoCrateReader reader = new RoCrateReader(new FolderReader());
        RoCrate crate = reader.readCrate(QuickStartWrite.TMP_EXAMPLE_CRATE);
        SchemaFacade schemaFacade = SchemaFacade.of(crate);

        List types = schemaFacade.getTypes();


        /* Writes out all types with their entries */
        for (IType type : types)
        {
            System.out.println(type);
            for (IMetadataEntry entry : schemaFacade.getEntries(type.getId()))
            {
                System.out.println(entry);
            }
        }
        /* Writes out all property types */
        for (IPropertyType propertyType : schemaFacade.getPropertyTypes())
        {
            System.out.println(propertyType);
        }

    }
}