SemWeb: Docs: Reading RDF

SemWeb Documentation

# Reading RDF

Reading RDF files is pretty easy so here are a few examples.

This loads an RDF/XML file into a MemoryStore:

    MemoryStore store = new MemoryStore();
    store.Import(new RdfXmlReader("data.rdf"));

This loads a N-Triples, Turtle, or Notation 3 file into a store:

    store.Import(new N3Reader("data.n3"));

This loads a RDF file from the web:

    store.Import(RdfReader.LoadFromUri(new Uri("http://www.mozilla.org/news.rdf")));

`LoadFromUri` will determine the format of the file (XML or N3) based on the MIME type sent back from the server, or if that fails, the file extension.

You don't have to put the contents of a file into memory. All of the `RdfReader`s are "streaming", which means it doesn't need to load the entire file before getting statements out of it. The reader can stream statements to a "sink" as soon as each is read.

In fact, readers are one type of `StatementSource`. `StatementSource`s provide a `Select` method which streams statements to a `StatementSink`, providing a corresponding `Add` method.

Stores are one type of sink. You saw the `MemoryStore`'s Add method in the last tutorial.

The following is pretty much equivalent to the code above:

    RdfReader webrdf = RdfReader.LoadFromUri(new Uri("http://www.mozilla.org/news.rdf"));
    webrdf.Select(store);

For a `MemoryStore`, there is no difference. Other stores may override `Import` with transaction or locking mechanics to speed up the process of loading a large data file.

By creating your own sink, you can process statements in a streaming way:

    class StatementPrinter : StatementSink {
        public bool Add(Statement assertion) {
            Console.WriteLine(assertion.ToString());
            return true;
        }
    }

This class implements a sink that simply prints out each statement to the console as each statement is received. It returns `true` to indicate to the source to continue. Returning `false` would end the streaming.

The `Statement` type is a struct that contains three fields: `Subject`, `Predicate`, and `Object` (actually it contains a `Meta` field too). Since RDF statements only have entities as subjects and predicates, the first two fields are typed as `Entity`, while the last field is typed as `Resource`. If you want to access the URIs and literal values within the statement, you might write something like this:

    Console.WriteLine("Subject: " + assertion.Subject.Uri);
    Console.WriteLine("Predicate: " + assertion.Predicate.Uri);
    if (assertion.Object is Entity)
        Console.WriteLine("Object: " + ((Entity)assertion.Object).Uri + " (it's an entity)");
    else
        Console.WriteLine("Object: " + ((Literal)assertion.Object).Value + " (it's a literal)");

Of course, beware that BNodes are entities without URIs, and the `Uri` property will return `null` in that case.

To stream the statements from the web directly to the custom sink, use:

    webrdf.Select(new StatementPrinter());

There's one final twist. Stores, as I mentioned, are a type of sink, letting you stream statements into them. They are simultaneously a type of source! This lets you stream statements out of them too, just as you stream statements out of the `RdfXmlReader` and into your own class.