# Creating RDF triples

## Creating Nodes

RDF is a graph where the nodes are URI references, Blank Nodes or Literals, in RDFLib represented by the classes `URIRef`, `BNode`, and `Literal`. `URIRefs` and `BNodes` can both be thought of as resources, such a person, a company, a web-site, etc. A `BNode` is a node where the exact URI is not known. `URIRefs` are also used to represent the properties/predicates in the RDF graph. `Literals` represent attribute values, such as a name, a date, a number, etc.

Nodes can be created by the constructors of the node classes:

    from rdflib import URIRef, BNode, Literal

    bob = URIRef("http://example.org/people/Bob")
    linda = BNode() # a GUID is generated

    name = Literal('Bob') # passing a string
    age = Literal(24) # passing a python int
    height = Literal(76.5) # passing a python float

Literals can be created from python objects, this creates `data-typed literals`, for the details on the mapping see Literals.

For creating many `URIRefs` in the same `namespace`, i.e. URIs with the same prefix, RDFLib has the `rdflib.namespace.Namespace` class:

    from rdflib import Namespace

    n = Namespace("http://example.org/people/")

    n.bob # = rdflib.term.URIRef(u'http://example.org/people/bob')
    n.eve # = rdflib.term.URIRef(u'http://example.org/people/eve')

This is very useful for schemas where all properties and classes have the same URI prefix, RDFLib pre-defines Namespaces for the most common RDF schemas:

    from rdflib.namespace import RDF, FOAF

    RDF.type
    # = rdflib.term.URIRef(u'http://www.w3.org/1999/02/22-rdf-syntax-ns#type')

    FOAF.knows
    # = rdflib.term.URIRef(u'http://xmlns.com/foaf/0.1/knows')

## Adding Triples

We already saw in Loading and saving RDF, how triples can be added with with the `parse()` function.

Triples can also be added with the `add()` function:

`Graph.``add`(xxx_todo_changeme)

  Add a triple with self as context

`add()` takes a 3-tuple of RDFLib nodes. Try the following with the nodes and namespaces we defined previously:

    from rdflib import Graph
    g = Graph()

    g.add( (bob, RDF.type, FOAF.Person) )
    g.add( (bob, FOAF.name, name) )
    g.add( (bob, FOAF.knows, linda) )
    g.add( (linda, RDF.type, FOAF.Person) )
    g.add( (linda, FOAF.name, Literal('Linda') ) )

    print g.serialize(format='turtle')

outputs:

    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix xml: <http://www.w3.org/XML/1998/namespace> .

    <http://example.org/people/Bob> a foaf:Person ;
            foaf:knows [ a foaf:Person ;
                            foaf:name "Linda" ] ;
            foaf:name "Bob" .

For some properties, only one value per resource makes sense (i.e they are functional properties, or have max-cardinality of 1). The `set()` method is useful for this:

    g.add( ( bob, FOAF.age, Literal(42) ) )
    print "Bob is ", g.value( bob, FOAF.age )
    # prints: Bob is 42

    g.set( ( bob, FOAF.age, Literal(43) ) ) # replaces 42 set above
    print "Bob is now ", g.value( bob, FOAF.age )
    # prints: Bob is now 43

`rdflib.graph.Graph.value()` is the matching query method, it will return a single value for a property, optionally raising an exception if there are more.

You can also add triples by combining entire graphs, see Set Operations on RDFLib Graphs.

### Removing Triples

Similarly, triples can be removed by a call to `remove()`:

`Graph.``remove`(xxx_todo_changeme1)

  Remove a triple from the graph

  If the triple does not provide a context attribute, removes the triple from all contexts.

When removing, it is possible to leave parts of the triple unspecified (i.e. passing `None`), this will remove all matching triples:

    g.remove( (bob, None, None) ) # remove all triples about bob

### An example

LiveJournal produces FOAF data for their users, but they seem to use `foaf:member_name` for a person’s full name. To align with data from other sources, it would be nice to have `foaf:name` act as a synonym for `foaf:member_name` (a poor man’s one-way `owl:equivalentProperty`):

    from rdflib.namespace import FOAF
    g.parse("http://danbri.livejournal.com/data/foaf")
    for s,_,n in g.triples((None, FOAF['member_name'], None)):
        g.add((s, FOAF['name'], n))