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 Statements 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);
        }
    }
}