Processing RDF
The crate rudof_rdf contains several traits and implementations that can be useful to process RDF.
The architecture of rudof RDF is based on a set of generic traits, in rudof_rdf::rdf_core, with concrete implementations in rudof_rdf::rdf_impl.
The main traits are:
- Rdf: the base trait. Defines the associated types shared by every implementation (
Subject,IRI,Term,BNode,Literal,Triple) and basic conversions/comparisons between them. - NeighsRDF: extends
Rdfwith methods to get basic information from RDF graphs required for validating RDF graphs. Mainly get the neighbourhood of RDF nodes (incoming/outgoing arcs, predicates of a subject, triples with some predicate, etc.), and follow SHACL property paths. - BuildRDF: extends
NeighsRDFwith methods to build RDF data — add/remove triples, manage prefixes and the base IRI, and serialize the graph. - FocusRDF: extends
NeighsRDFwith a "focus node", a current point of reference in the graph that parsing operations (e.g. SHACL/ShEx validation) can navigate from without repeatedly specifying it. - QueryRDF: extends
Rdfwith SPARQL query support (SELECT, CONSTRUCT, ASK). - AsyncRDF: an async counterpart of the above, used by backends whose work is inherently asynchronous (Docker, HTTP), such as the QLever backend.
- RDFNodeParse: a generic parser of RDF data inspired by the concept of parser combinators, where the input is an RDF node instead of a sequence of characters. Some parts of this code are inspired by the Combine parser combinators library — see Parsing RDF for more.
The previous traits are implemented by the following concrete types, in rudof_rdf::rdf_impl:
- OxigraphInMemory: implementation of the previous traits based on an in-memory RDF graph using oxrdf. This is what
data,shex,shacl, etc. use by default. - OxigraphEndpoint: implementation based on a remote SPARQL endpoint.
QleverGraphContainer(behind theqleverfeature): implementation backed by a local QLever Docker container. See the--backendreference for how backends are selected from the CLI.
If you want to handle RDF in a generic way, our recommendation is to write your code against the traits (
Rdf,NeighsRDF,BuildRDF, ...) rather than a concrete type. In that way, your code could work with an in-memory graph, a SPARQL endpoint, or the QLever backend without having to modify the code.
Example: Creating an RDF graph
The following code can be used to create a triple in an RDF graph in memory:
#![allow(unused)] fn main() { use rudof_iri::iri; use rudof_rdf::rdf_core::BuildRDF; use rudof_rdf::rdf_impl::OxigraphInMemory; let mut graph = OxigraphInMemory::new(); let alice = iri!("http://example.org/alice"); let knows = iri!("http://example.org/knows"); let bob = iri!("http://example.org/bob"); graph.add_triple(alice, knows, bob).unwrap(); assert_eq!(graph.len(), 1); }