RDF Core
Parse, serialize, and query RDF graphs and datasets.
W3C RDF 1.1 compliant core library for Dart.
Getting Started
Install the package
dart pub add locorda_rdf_core import 'package:locorda_rdf_core/core.dart';
void main() {
final turtleData = '''
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example.org/alice> foaf:name "Alice"@en .
''';
final graph = turtle.decode(turtleData);
print('Triples: ${graph.triples.length}'); // Triples: 1
} import 'package:locorda_rdf_core/core.dart';
void main() {
// Create individual triples
final alice = const IriTerm('http://example.org/alice');
final foafName = const IriTerm('http://xmlns.com/foaf/0.1/name');
final foafAge = const IriTerm('http://xmlns.com/foaf/0.1/age');
final triple = Triple(alice, foafName, LiteralTerm.string('Alice'));
// Create graph from triples
final graph = RdfGraph(triples: [triple]);
print('Created graph with ${graph.triples.length} triple(s)');
// Add more triples (immutable - returns new graph)
final updatedGraph = graph.withTriple(
Triple(alice, foafAge, LiteralTerm.integer(30)),
);
print('Updated graph has ${updatedGraph.triples.length} triples');
// Note: For parsing, use turtle.decode(data) instead
print('\nTurtle output:');
print(turtle.encode(updatedGraph));
} import 'package:locorda_rdf_core/core.dart';
void main() {
// Create quads with graph context
final alice = const IriTerm('http://example.org/alice');
final bob = const IriTerm('http://example.org/bob');
final foafName = const IriTerm('http://xmlns.com/foaf/0.1/name');
final foafKnows = const IriTerm('http://xmlns.com/foaf/0.1/knows');
final peopleGraph = const IriTerm('http://example.org/graphs/people');
final quads = [
Quad(alice, foafName, LiteralTerm.string('Alice')), // default graph
Quad(alice, foafKnows, bob, peopleGraph), // named graph
Quad(bob, foafName, LiteralTerm.string('Bob'), peopleGraph), // named graph
];
// Create dataset from quads
final dataset = RdfDataset.fromQuads(quads);
// Encode to N-Quads
final nquadsData = nquads.encode(dataset);
print('N-Quads output:');
print(nquadsData);
// Decode N-Quads back to dataset
final decodedDataset = nquads.decode(nquadsData);
// Access default and named graphs
print(
'Default graph has ${decodedDataset.defaultGraph.triples.length} triples');
print('Dataset has ${decodedDataset.namedGraphs.length} named graphs');
for (final namedGraph in decodedDataset.namedGraphs) {
print(
'Named graph ${namedGraph.name} has ${namedGraph.graph.triples.length} triples');
}
} import 'package:locorda_rdf_core/core.dart';
void main() {
// Start with a graph
final alice = const IriTerm('http://example.org/alice');
final bob = const IriTerm('http://example.org/bob');
final charlie = const IriTerm('http://example.org/charlie');
final foafKnows = const IriTerm('http://xmlns.com/foaf/0.1/knows');
final graph = RdfGraph(triples: [
Triple(alice, foafKnows, bob),
Triple(bob, foafKnows, charlie),
]);
// Query: Find all "knows" relationships
final knowsTriples = graph.findTriples(predicate: foafKnows);
print('People who know someone:');
for (final triple in knowsTriples) {
print(' ${triple.subject} knows ${triple.object}');
}
// Update: Add new triple (returns new immutable graph)
final updatedGraph = graph.withTriple(Triple(alice, foafKnows, charlie));
print('\nTotal triples: ${updatedGraph.triples.length}');
// Check existence
if (updatedGraph.hasTriples(subject: alice, object: charlie)) {
print('Alice knows Charlie!');
}
} import 'package:locorda_rdf_core/core.dart';
void main() {
final turtleData = '''
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example.org/alice> foaf:name "Alice" ;
foaf:age 30 .
''';
// Parse Turtle
final graph = rdf.decode(turtleData, contentType: 'text/turtle');
print('Parsed ${graph.triples.length} triples');
// Convert to N-Triples
final ntriples = rdf.encode(graph, contentType: 'application/n-triples');
print('\nN-Triples:\n$ntriples');
} // ignore_for_file: unused_local_variable
import 'package:locorda_rdf_core/core.dart';
// import 'package:locorda_rdf_xml/xml.dart';
void main() {
// Example 1: Customize Turtle parsing for SPARQL-style syntax
print('1. Custom Turtle codec for SPARQL-style files:');
final sparqlStyleTurtle = TurtleCodec(
decoderOptions: TurtleDecoderOptions(
parsingFlags: {
TurtleParsingFlag.allowMissingDotAfterPrefix,
TurtleParsingFlag.allowPrefixWithoutAtSign,
},
),
);
final customRdf = RdfCore.withCodecs(codecs: [
sparqlStyleTurtle,
NTriplesCodec(),
]);
// Parse SPARQL-style Turtle (no @ before PREFIX, no . after prefix)
final sparqlData = '''
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
<http://example.org/alice> foaf:name "Alice" .
''';
final graph = customRdf.decode(sparqlData, contentType: 'text/turtle');
print(' Parsed ${graph.triples.length} triples from SPARQL-style syntax\n');
// Example 2: Add RDF/XML support via extension package
print('2. Extending with RDF/XML support:');
final xmlRdf = RdfCore.withCodecs(codecs: [
TurtleCodec(),
NTriplesCodec(),
// RdfXmlCodec(), // from locorda_rdf_xml package
]);
final xmlData = '''
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/">
<rdf:Description rdf:about="http://example.org/alice">
<foaf:name>Alice</foaf:name>
</rdf:Description>
</rdf:RDF>
''';
// final xmlGraph = xmlRdf.decode(xmlData, contentType: 'application/rdf+xml');
// print(' Parsed ${xmlGraph.triples.length} triples from RDF/XML');
print(' Add locorda_rdf_xml to pubspec.yaml for RDF/XML support');
print(' Extensible architecture: any codec can be added!');
} What Can You Build?
ποΈ Knowledge Graphs
Build semantic knowledge bases with typed relationships. Perfect for domain modeling, ontologies, and linked data applications.
π Data Integration
Merge data from multiple sources into a unified graph. Transform between formats (Turtle β N-Triples β N-Quads) seamlessly. Additional formats like JSON-LD, RDF/XML, and Jelly are available via companion packages.
οΏ½ In-Memory Graph Queries
Graph queries with O(1) subject lookups. Automatic indexing makes complex queries efficient for datasets that fit in RAM.
Key Features
Automatic Performance Optimization
Lazy indexing provides O(1) subject-based queries with zero memory cost until first use. Queries benefit from transparent performance improvements.
Developer-Friendly API
Global convenience variables (turtle, ntriples) make parsing trivial. Fluent APIs for graph composition and chaining. Additional format packages follow the same convention.
Built-in Text Formats
Parse and serialize Turtle, N-Triples, and N-Quads out of the box. Extend with additional format packages for JSON-LD, RDF/XML, or the high-performance Jelly binary format.
Full Dataset Support
Work with named graphs and datasets. Complete quad support for N-Quads with RDF 1.1 Dataset compliance.
Type-Safe
Strongly-typed Dart APIs with full IDE support and autocompletion. Catch errors at compile time.
Zero Dependencies
No external dependencies except logging. Clean, maintainable codebase.
Yeah fine, but:
π "I want to work with Person and Book, not Triples"
β Use mapper (annotations + generator)
Define your domain model with annotations. The generator creates bidirectional mappings between your classes and RDF.
π·οΈ "I need JSON-LD"
β Use locorda_rdf_jsonld
Full JSON-LD 1.1 support: expansion, compaction, flattening, toRdf and fromRdf. W3C conformance tested. Plugs into RdfCore alongside other codecs.
π "Do you support RDF/XML?"
β Yes, via locorda_rdf_xml
Full RDF/XML encoder and decoder for legacy format support and interoperability with older systems.
β‘ "I need high-performance binary encoding"
β Use locorda_rdf_jelly
Jelly is a streaming binary format based on Protocol Buffers. Fastest encoder and decoder in the suite β significantly smaller output than Turtle or N-Triples.
π© "Typing IRIs is hell"
β Use terms and vocabularies
Type-safe constants for Schema.org, FOAF, Dublin Core, and more. Never typo a property URI again.
π "Can you canonicalize?"
β Yes, canonicalization
RDF-CANON (RDFC-1.0) support for canonical serialization, reliable graph comparison, and cryptographic signing.
Ready to Start?
Read the documentation or explore other RDF packages.