This guide shows how to use the CDI Viewer as a general-purpose JSON-LD editor and SHACL validator for any RDF vocabulary.
Note: By default, the viewer loads in DDI-CDI mode (since the tool is named cdi-viewer). To use it with other vocabularies:
- Generic mode: https://libis.github.io/cdi-viewer/?shacl=generic
- No shapes preloaded - Select from dropdown or enter custom URL
- Getting Started
- Supported Vocabularies
- Loading Custom SHACL Shapes
- Editing Workflow
- Advanced Features
- Common Patterns
-
Prepare your JSON-LD file
- Any valid JSON-LD with
@contextand@graph(or single object) - Can use prefixed or expanded forms
- Supports nested objects and references
- Any valid JSON-LD with
-
Find or create SHACL shapes
- Use built-in shapes (schema.org, DCAT, DataCube, SKOS)
- Load from URL (must be Turtle format)
- Create custom shapes for your vocabulary
-
Load and edit in the viewer
- Visual property classification (REQUIRED/OPTIONAL/EXTRA)
- Smart input types based on SHACL constraints
- Real-time validation feedback
-
Export validated JSON-LD
- Download modified file
- Use in your application
- Upload to Dataverse or other system
The viewer works with any JSON-LD vocabulary. Here are common examples:
Perfect for web-visible metadata (Google Dataset Search, etc.)
Example:
{
"@context": "https://schema.org/",
"@type": "Dataset",
"name": "Climate Data 2024",
"description": "Temperature readings",
"creator": {
"@type": "Person",
"name": "Jane Smith",
"affiliation": "University Lab"
},
"distribution": {
"@type": "DataDownload",
"contentUrl": "https://example.org/data.csv"
}
}SHACL shapes: Create custom shapes or use schema.org's type hierarchy for validation.
For data catalogs and open data portals.
Example:
{
"@context": "http://www.w3.org/ns/dcat#",
"@type": "Catalog",
"title": "Research Data Catalog",
"dataset": [
{
"@type": "Dataset",
"title": "Sample Dataset",
"distribution": {
"@type": "Distribution",
"accessURL": "https://example.org/data"
}
}
]
}SHACL shapes: Built-in DCAT-AP 3.0 shapes (dcat-ap-3.0)
For people and social networks.
Example:
{
"@context": "http://xmlns.com/foaf/0.1/",
"@type": "Person",
"name": "John Doe",
"mbox": "mailto:john@example.org",
"knows": {
"@type": "Person",
"name": "Jane Smith"
}
}SHACL shapes: Find FOAF SHACL shapes in SHACL Catalog
For library metadata and general resource description.
Example:
{
"@context": "http://purl.org/dc/terms/",
"@type": "Text",
"title": "Research Paper",
"creator": "John Doe",
"subject": "Machine Learning",
"date": "2024-01-01"
}SHACL shapes: Create custom shapes based on Dublin Core properties
- Select "Custom URL" from the SHACL dropdown
- Enter the full URL to your
.ttlfile - Click "Load Custom Shapes"
Requirements:
- Must be Turtle format (
.ttl) - Must use Core SHACL features only (no SPARQL constraints)
- Must be accessible via HTTPS with CORS enabled
Example URLs:
# GitHub raw content
https://raw.githubusercontent.com/username/repo/main/shapes.ttl
# Permanent identifier
https://w3id.org/my-vocab/shapes.ttl
# Direct link
https://example.org/shapes/my-shapes.ttl
Minimal SHACL shape example:
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix schema: <https://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
schema:DatasetShape
a sh:NodeShape ;
sh:targetClass schema:Dataset ;
sh:property [
sh:path schema:name ;
sh:name "Name" ;
sh:description "The name of the dataset" ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path schema:description ;
sh:name "Description" ;
sh:description "A description of the dataset" ;
sh:datatype xsd:string ;
sh:minCount 1 ;
] ;
sh:property [
sh:path schema:creator ;
sh:name "Creator" ;
sh:description "The creator of the dataset" ;
sh:node schema:PersonShape ;
] .
schema:PersonShape
a sh:NodeShape ;
sh:targetClass schema:Person ;
sh:property [
sh:path schema:name ;
sh:name "Name" ;
sh:datatype xsd:string ;
sh:minCount 1 ;
] .Key SHACL properties used by the viewer:
sh:path- Property being constrained (maps to JSON-LD key)sh:name- Human-readable label shown in UIsh:description- Help text shown as tooltipsh:datatype- Controls input type (xsd:string, xsd:integer, xsd:date, etc.)sh:minCount- If > 0, marked as REQUIREDsh:maxCount- Controls array behavior (1 = single value)sh:nodeorsh:class- For complex objects/referencessh:in- For enumerated values (dropdown)
-
Load your JSON-LD file
- Click "Load Local File" or provide URL parameter
- File automatically normalized to
@graphformat
-
Load SHACL shapes
- Select from built-in options or provide custom URL
- Shapes load asynchronously
-
Review structure
- Root nodes shown as expandable cards
- Referenced nodes nested inline
- Properties classified with color badges
Simple values:
- Click in input field and type
- Changes marked with teal highlight
- Validation updates in real-time
Dates:
- Click date picker icon
- Select date from calendar
- Format: YYYY-MM-DD (ISO 8601)
Enumerations:
- Select from dropdown (if
sh:inconstraint) - Only valid values allowed
URIs:
- Text input with URI validation
- Can paste full URLs
From SHACL suggestions:
- Scroll to "Add Properties" section
- Select property from searchable dropdown
- Click "Add Property"
- Required properties marked with
⚠️
Custom properties:
- Click "Add Custom Property"
- Enter property name
- Property added as text input
Convert single → array:
- Click "Convert to Array" button
- Current value becomes first array element
- Click "Add Value" to add more items
Convert array → single:
- Click "Convert to Single Value"
- Confirm action (only first value kept)
Add to array:
- "Add Value" - Add simple text/number value
- "Add Reference/Object" - Add reference or create nested object
Create nested object:
- Click "Add Reference/Object" on any property
- Modal opens with two options:
- Reference existing node - Select from dropdown
- Create new object - Enter type name
- Click "Add"
- New node renders inline for editing
Reference existing node:
- Choose "Reference existing node"
- Select from dropdown (shows all
@idvalues) - Creates
{"@id": "..."}reference - Renders as clickable jump button
Validation:
- Automatic after loading shapes
- Click "Validate" button to re-run
- Results shown with:
- Total violations count
- List of specific issues
- Links to problematic properties
Export:
- Click "Export JSON-LD"
- File downloads with all changes
- Original
@contextpreserved - Structure maintained
- Collapsible nodes - Click header to collapse/expand
- Nested rendering - Referenced nodes shown inline
- Indentation - Visual hierarchy for nested objects
- Jump buttons - Click reference to scroll to target node
Visual badges show property status:
- 🔵 OPTIONAL - In SHACL shapes but not required (sh:minCount = 0 or unspecified)
- 🔴 REQUIRED - In SHACL shapes with sh:minCount > 0
- 🟡 EXTRA - Not in SHACL shapes (custom properties)
- 🔷 CHANGED - Modified in edit mode
Automatically detected from SHACL sh:datatype:
| SHACL Datatype | Input Type | Example |
|---|---|---|
xsd:string |
Text input | "Sample text" |
xsd:integer |
Number input | 42 |
xsd:decimal |
Number input | 3.14 |
xsd:date |
Date picker | 2024-01-01 |
xsd:dateTime |
Datetime input | 2024-01-01T12:00:00 |
xsd:boolean |
Checkbox | true/false |
xsd:anyURI |
URL input | https://example.org |
The viewer respects SHACL cardinality constraints:
sh:maxCount 1- Single value only (no array)- No
sh:maxCount- Can be array or single value sh:minCount 1- Required (cannot delete)sh:minCount 0or unspecified - Optional (can delete)
Automatically generated for nested objects:
- Format:
_:propertyName_timestamp - Behavior: Always rendered inline (never as root nodes)
- Editing: Full editing capabilities just like named nodes
{
"@context": "https://schema.org/",
"@graph": [
{
"@type": "Dataset",
"@id": "http://example.org/dataset/1",
"name": "My Dataset",
"creator": { "@id": "_:person1" }
},
{
"@type": "Person",
"@id": "_:person1",
"name": "Jane Smith",
"affiliation": "University Lab"
}
]
}How to create:
- Add "creator" property
- Click "Add Reference/Object"
- Choose "Create new object"
- Enter type: "Person"
- Edit nested Person properties
{
"@type": "Dataset",
"keywords": ["climate", "temperature", "weather"]
}How to create:
- Add "keywords" property (text input)
- Click "Convert to Array"
- Click "Add Value" for each keyword
{
"@type": "Dataset",
"distribution": [
{
"@type": "DataDownload",
"contentUrl": "https://example.org/data.csv",
"encodingFormat": "text/csv"
},
{
"@type": "DataDownload",
"contentUrl": "https://example.org/data.json",
"encodingFormat": "application/json"
}
]
}How to create:
- Add "distribution" property
- Click "Add Reference/Object"
- Create DataDownload object
- Click "Convert to Array" on distribution
- Click "Add Reference/Object" again for second distribution
{
"@graph": [
{
"@type": "Dataset",
"@id": "http://example.org/dataset/1",
"subject": [
{ "@id": "http://example.org/concept/climate" },
{ "@id": "http://example.org/concept/ocean" }
]
},
{
"@type": "Concept",
"@id": "http://example.org/concept/climate",
"prefLabel": "Climate Science"
},
{
"@type": "Concept",
"@id": "http://example.org/concept/ocean",
"prefLabel": "Oceanography"
}
]
}How to create:
- Create Concept nodes first (manually or via UI)
- Add "subject" property to Dataset
- Click "Add Reference/Object"
- Select existing concept from dropdown
- Repeat for additional references
✅ Do:
- Use descriptive
sh:namevalues (shown in UI) - Add
sh:descriptionfor help text - Specify
sh:datatypefor proper input types - Use
sh:infor controlled vocabularies - Set
sh:minCountfor required fields
❌ Don't:
- Use SPARQL-based constraints (not supported in browser)
- Omit
sh:path(required for property mapping) - Use complex
sh:or/sh:andlogic (may not render well)
- Large files (>1MB): May take a few seconds to parse
- Many shapes: Initial validation may take 1-2 seconds
- Deep nesting: Keep nesting levels reasonable (<5 levels)
- Modern browsers: Chrome, Firefox, Safari, Edge (latest versions)
- JavaScript required: No graceful degradation
- Local storage: Used for caching shapes (must be enabled)
- SPARQL constraints: Not supported (use Core SHACL only)
- Named graphs: Only
@grapharray supported - File size: Practical limit ~10MB (browser memory constraints)
- Concurrent editing: Single user only (no real-time collaboration)
Problem: Shapes don't load from URL
Solution: Check:
- URL returns Turtle format (not HTML)
- CORS headers enabled on server
- No syntax errors in Turtle file
- Network console for specific error
Problem: Properties show as EXTRA but should be in shapes
Solution:
- Verify
sh:pathexactly matches JSON-LD property key - Check namespace prefixes match
@context - Try expanded form if prefixed form doesn't match
Problem: Can't add complex property
Solution:
- Ensure SHACL shape has
sh:nodeorsh:class - Check that target class has a NodeShape definition
- Verify blank nodes aren't blocked by validation rules
Problem: Validation always shows errors
Solution:
- Check SHACL shapes are valid (test with pySHACL)
- Verify your JSON-LD structure matches shape expectations
- Look at specific violation messages for clues
- JSON-LD Playground: https://json-ld.org/playground/
- SHACL Playground: https://shacl.org/playground/
- W3C SHACL Spec: https://www.w3.org/TR/shacl/
- W3C JSON-LD Spec: https://www.w3.org/TR/json-ld11/
- schema.org: https://schema.org/
- DCAT Vocabulary: https://www.w3.org/TR/vocab-dcat-3/
- GitHub Issues: https://github.com/libis/cdi-viewer/issues
- Documentation: See main README.md
- Examples: See
examples/directory for DDI-CDI samples
Made with ❤️ by LIBIS @ KU Leuven