SemWeb: Docs: Hello World

SemWeb Documentation

# SemWeb Hello World

Here's an example of using SemWeb to construct an RDF/XML or Notation 3 file.

Create a new file called `helloworld.cs`. If you're using Visual Studio, create this in a new project and reference `SemWeb.dll` provided in the download package.

First, use the relevant namespaces and create a simple class. Also add a constant for the RDF namespace.

    using System;
    using SemWeb;

    public class Example {
    	const string RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";

    	public static void Main() {
    	}
    }

In `Main()`, create a new `MemoryStore`, which is an in-memory store of RDF statements:

    MemoryStore store = new MemoryStore();

The next thing to do is create some entities for the things you will be asserting statements about. You can do that simply by creating a new `Entity` object:

    Entity computer = new Entity("http://example.org/computer");
    Entity description = new Entity("http://example.org/description");

The `Entity` class has an implicit conversion operator from strings, which means you can just assign a string to an entity variable to save typing:

    Entity says = "http://example.org/says";
    Entity wants = "http://example.org/wants";

Blank nodes, a.k.a. anonymous entities, are created using the `BNode` class, which is a subclass of `Entity`.

    Entity desire = new BNode();

Next, we create statements using these entities. To create a statement, use the `Statement` constructor, which takes a subject, predicate, and object. Note that `Statement`s are structs, not classes, but this probably won't affect you.

    Statement assertion = new Statement(computer, says, new Literal("Hello world!"));

Another conversion operator is defined to make it easy for you to create Literals out of strings. Unlike the one that is implict for Entities, this one is explicit, which means you always need to write out the cast. We could have written the previous line like this insted:

    Statement assertion = new Statement(computer, says, (Literal)"Hello world!");

Statements have to be put into a `Store` like this:

    store.Add(assertion);

I'll condense that into this:

    store.Add(new Statement(computer, says, (Literal)"Hello world!"));
    store.Add(new Statement(computer, wants, desire));
    store.Add(new Statement(desire, description, (Literal)"to be human"));
    store.Add(new Statement(desire, RDF+"type", (Entity)"http://example.org/Desire"));

A store is a collection of statements. In true RDF, the order and number of occurrences of a statement doesn't matter because a graph is simply a set of statements. Some SemWeb stores act like sets, rather than collections. The memory store is not one of these.

Lastly, we want to write out the contents of the store to an RDF/XML file. We do this by creating a new `RdfXmlWriter` object, sending the store's contents to the writer, and then disposing the writer. It's very important to dispose of writers so they can finish, so you should always wrap writers with the using C# directive.

    using (RdfWriter writer = new RdfXmlWriter(Console.Out)) {
        writer.Write(store);
    }

If you're using Mono, like I do, to compile and run the program, run the following commands. Be sure to put `SemWeb.dll` in the current directory so Mono can find it at compile time, and then at run time.

    mcs helloworld.cs -r:SemWeb.dll
    mono helloworld.exe

If you're using VisualStudio, put this in a new project, reference `SemWeb.dll` and compile and run it.

Here's the output:

    <?xml version="1.0"?>
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:exampleorg="http://example.org/">
        <rdf:Description rdf:about="http://example.org/computer">
            <exampleorg:says>Hello world!</exampleorg:says>
            <exampleorg:wants>
                <exampleorg:Desire>
                    <exampleorg:description>to be human</exampleorg:description>
                </exampleorg:Desire>
            </exampleorg:wants>
        </rdf:Description>
    </rdf:RDF>

We didn't provide the writer with any namespace prefixes, so it made one up. To provide a prefix for a namespace, use the `Namespaces` property of the writer:

    using (RdfWriter writer = new RdfXmlWriter(Console.Out)) {
        writer.Namespaces.AddNamespace("http://example.org/", "ex");
        ...

You need to set the namespaces before any statements are streamed to the writer. Here's the final output:

    <?xml version="1.0"?>
    <rdf:RDF xmlns:ex="http://example.org/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:Description rdf:about="http://example.org/computer">
            <ex:says>Hello world!</ex:says>
            <ex:wants>
                <ex:Desire>
                    <ex:description>to be human</ex:description>
                </ex:Desire>
            </ex:wants>
        </rdf:Description>
    </rdf:RDF>

To write out the statements in Notation 3 format, just use the `N3Writer` class instead. It produces this output:

    @prefix ex: <http://example.org/> .
    ex:computer ex:says "Hello world!" ;
        ex:wants _:bnode0 .
    _:bnode0 ex:description "to be human" ;
        <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ex:Desire .

Here's the complete program:

    // This example creates a few RDF statements and adds
    // them to a MemoryStore.  Then it writes out the
    // statements in RDF/XML format to the console.  Note
    // that the implicit string-to-Entity and string-to-
    // Literal conversion operators are being used.

    using System;
    using SemWeb;

    public class Example {

        const string RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";

        public static void Main() {
            MemoryStore store = new MemoryStore();

            Entity computer = new Entity("http://example.org/computer");
            Entity says = "http://example.org/says";
            Entity wants = "http://example.org/wants";
            Entity desire = new BNode();
            Entity description = new Entity("http://example.org/description");

            store.Add(new Statement(computer, says, (Literal)"Hello world!"));
            store.Add(new Statement(computer, wants, desire));
            store.Add(new Statement(desire, description, (Literal)"to be human"));
            store.Add(new Statement(desire, RDF+"type", (Entity)"http://example.org/Desire"));

            using (RdfWriter writer = new RdfXmlWriter(Console.Out)) {
                writer.Namespaces.AddNamespace("http://example.org/", "ex");
                writer.Write(store);
            }
        }
    }