rdf_core 0.8.0
rdf_core: ^0.8.0 copied to clipboard
A type-safe, modular Dart library for modeling, parsing, and serializing RDF data.
RDF Core #
A type-safe, and extensible Dart library for representing and manipulating RDF data without any further dependencies.
Core of a whole family of projects #
If you are looking for more rdf-related functionality, have a look at our companion projects:
- parse and serialize rdf/xml format: rdf_xml
- easy-to-use constants for many well-known vocabularies: rdf_vocabularies
- generate your own easy-to-use constants for other vocabularies with a build_runner: rdf_vocabulary_to_dart
- map Dart Objects βοΈ RDF: rdf_mapper
β¨ Features #
- Type-safe RDF model: IRIs, Literals, Triples, Graphs, and more
- Serialization-agnostic: Clean separation from Turtle/JSON-LD/N-Triples
- Extensible & modular: Build your own adapters, plugins, and integrations
- Spec-compliant: Follows W3C RDF 1.1 and related standards
- Convenience global variables: Easy usage with
turtle
,jsonld
andntriples
for quick encoding/decoding
π Quick Start #
Convenience Globals #
The library provides global variables for quick and easy access:
import 'package:rdf_core/rdf_core.dart';
// Easy access to formats through global variables
final graphFromTurtle = turtle.decode(turtleData);
final graphFromJsonLd = jsonld.decode(jsonLdData);
final graphFromNTriples = ntriples.decode(ntriplesData);
// Or use the pre-configured RdfCore instance
final graph = rdf.decode(data, contentType: 'text/turtle');
Manual Graph Creation #
import 'package:rdf_core/rdf_core.dart';
void main() {
final subject = IriTerm('http://example.org/alice');
final predicate = IriTerm('http://xmlns.com/foaf/0.1/name');
final object = LiteralTerm.withLanguage('Alice', 'en');
final triple = Triple(subject, predicate, object);
final graph = RdfGraph(triples: [triple]);
print(graph);
}
Parsing and Serializing Turtle #
import 'package:rdf_core/rdf_core.dart';
void main() {
// Example: Parse a simple Turtle document
final turtleData = '''
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example.org/alice> foaf:name "Alice"@en .
''';
// Option 1: Using the convenience global variable
final graph = turtle.decode(turtleData);
// Option 2: Using RdfCore instance
// final rdfCore = RdfCore.withStandardCodecs();
// final graph = rdfCore.decode(turtleData, contentType: 'text/turtle');
// Print parsed triples
for (final triple in graph.triples) {
print('${triple.subject} ${triple.predicate} ${triple.object}');
}
// Serialize the graph back to Turtle
final serialized = turtle.encode(graph);
print('\nSerialized Turtle:\n$serialized');
}
Parsing and Serializing N-Triples #
import 'package:rdf_core/rdf_core.dart';
void main() {
// Example: Parse a simple N-Triples document
final ntriplesData = '''
<http://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice"@en .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/knows> <http://example.org/bob> .
''';
// Using the convenience global variable
final graph = ntriples.decode(ntriplesData);
// Print parsed triples
for (final triple in graph.triples) {
print('${triple.subject} ${triple.predicate} ${triple.object}');
}
// Serialize the graph back to N-Triples
final serialized = ntriples.encode(graph);
print('\nSerialized N-Triples:\n$serialized');
}
Parsing and Serializing JSON-LD #
import 'package:rdf_core/rdf_core.dart';
void main() {
// Example: Parse a simple JSON-LD document
final jsonLdData = '''
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": {
"@id": "http://xmlns.com/foaf/0.1/knows",
"@type": "@id"
},
"Person": "http://xmlns.com/foaf/0.1/Person"
},
"@id": "http://example.org/alice",
"@type": "Person",
"name": "Alice",
"knows": [
{
"@id": "http://example.org/bob",
"@type": "Person",
"name": "Bob"
}
]
}
''';
// Using the convenience global variable
final graph = jsonld.decode(jsonLdData);
// Print parsed triples
for (final triple in graph.triples) {
print('${triple.subject} ${triple.predicate} ${triple.object}');
}
// Serialize the graph back to JSON-LD
final serialized = jsonld.encode(graph);
print('\nSerialized JSON-LD:\n$serialized');
}
π§βπ» Advanced Usage #
Parsing and Serializing RDF/XML #
With the help of the separate package rdf_xml you can easily serialize/deserialize RDF/XML as well.
dart pub add rdf_xml
import 'package:rdf_core/rdf_core.dart';
import 'package:rdf_xml/rdf_xml.dart';
void main() {
// Option 1: Use the codec directly
final graph = rdfxml.decode(rdfXmlData);
final serialized = rdfxml.encode(graph);
// Option 2: Register with RdfCore
final rdf = RdfCore.withStandardCodecs(additionalCodecs: [RdfXmlCodec()])
// Now it can be used with the rdf instance in addition to turtle etc.
final graphFromRdf = rdf.decode(rdfXmlData, contentType: 'application/rdf+xml');
}
Graph Merging #
final merged = graph1.merge(graph2);
Pattern Queries #
final results = graph.findTriples(subject: subject);
Blank Node Handling #
// Note: BlankNodeTerm is based on identity - if you call BlankNodeTerm()
// a second time, it will be a different blank node and get a different
// label in serialization formats. You have to reuse an instance, if you
// want to refer to the same blank node.
final bnode = BlankNodeTerm();
final newGraph = graph.withTriple(Triple(bnode, predicate, object));
Non-Standard Turtle Parsing #
import 'package:rdf_core/rdf_core.dart';
// Configure a custom TurtleCodec with specific parsing flags
final customTurtleCodec = TurtleCodec(
parsingFlags: {
TurtleParsingFlag.allowDigitInLocalName,
TurtleParsingFlag.allowMissingDotAfterPrefix,
TurtleParsingFlag.autoAddCommonPrefixes,
}
);
// Option 1: Use the custom codec directly
final nonStandardTurtle = '''
@prefix ex: <http://example.org/> // Missing dot after prefix
ex:resource123 a ex:Type . // Digit in local name
''';
final graph = customTurtleCodec.decode(nonStandardTurtle);
// Option 2: Register the custom codec with an RdfCore instance - note that this
// time we register only the specified codecs here. If we want jsonld, we have to
// add it to the list as well.
final customRdf = RdfCore.withCodecs(codecs: [customTurtleCodec]);
final graph2 = customRdf.decode(nonStandardTurtle, contentType: 'text/turtle');
β οΈ Error Handling #
- All core methods throw Dart exceptions (e.g.,
ArgumentError
,RdfValidationException
) for invalid input or constraint violations. - Catch and handle exceptions for robust RDF processing.
π¦ Performance #
- Triple, Term, and IRI equality/hashCode are O(1)
- Graph queries (
findTriples
) are O(n) in the number of triples - Designed for large-scale, high-performance RDF workloads
πΊοΈ API Overview #
Type | Description |
---|---|
IriTerm |
Represents an IRI (Internationalized Resource Identifier) |
LiteralTerm |
Represents an RDF literal value |
BlankNodeTerm |
Represents a blank node |
Triple |
Atomic RDF statement (subject, predicate, object) |
RdfGraph |
Collection of RDF triples |
RdfCodec |
Base class for decoding/encoding RDF in various formats |
RdfDecoder |
Base class for decoding RDF |
RdfEncoder |
Base class for encoding RDF |
turtle |
Global convenience variable for Turtle format |
jsonld |
Global convenience variable for JSON-LD format |
ntriples |
Global convenience variable for N-Triples format |
rdf |
Global RdfCore instance with standard codecs |
π Standards & References #
π£οΈ Roadmap / Next Steps #
- Support base uri in jsonld and turtle serialization
- Improve jsonld parser/serializer (and include realworld tests for e.g. foaf.jsonld)
- Named Graphs (maybe as separate project)
- Rdf-Star
- SHACL and schema validation
- Performance optimizations for large graphs
- streaming parsing and serialization
π€ Contributing #
Contributions, bug reports, and feature requests are welcome!
- Fork the repo and submit a PR
- See CONTRIBUTING.md for guidelines
- Join the discussion in GitHub Issues
π€ AI Policy #
This project is proudly human-led and human-controlled, with all key decisions, design, and code reviews made by people. At the same time, it stands on the shoulders of LLM giants: generative AI tools are used throughout the development process to accelerate iteration, inspire new ideas, and improve documentation quality. We believe that combining human expertise with the best of AI leads to higher-quality, more innovative open source software.
Β© 2025 Klas KalaΓ. Licensed under the MIT License.