7.1. Triples in RDF/XML

The data model of RDF is deceptively simple: it merely defines a directed binary relation between two resources: the binary relation is called a predicate or a property; the two resources are subject and object. These three elements form a triple and they are all identified by URIs. An object can be a constant data value instead of a URI but the subject and predicate must be URIs. Table 7.1 shows different equivalent notations for an RDF triple. The RDF/XML is the most widely used for storing and exchanging RDF information. The equivalent triple (or its more recent variant Turtle [88]) is easier for humans to type and to understand. The graphical form can also be useful to grasp relations between many resources, but it can become quite hairy when there are many resources and relations. A very useful tool for converting between different RDF notations is the RDF validator [79] which not only validates the input but can produce the corresponding graph or show the equivalent triples. Twinkle [89] provides a GUI interface to query RDF data, but it can also parse and produce the output of the queries in different notations of RDF.

Table 7.1. RDF Triples in different forms, all of them equivalent

Graphical form
Triple subject predicate object
Relational form predicate(subject,object)
<rdf:Description rdf:about="subject">
         <rdf:Description rdf:about="object"/>
Turtle subject ex:predicate object.

Going from top to bottom, we see: the graphical notation in which the subject and object are linked by a labelled arrow; the triple format in which each component is a URI or data value in the case of an object; the relational form that would be the equivalent in Prolog; the RDF/XML exchange format and the Turtle format which, in the case of a single triple, only differs from the triple notation by its use of namespace prefix in URIs.

Information is represented by a set of RDF triples, often called a model. As it is a set, there is no ordering, nor repetition between triples within a model. Information is encoded as a conjunction of triples. Negation and disjunction cannot be expressed in RDF.

Figure 7.2. Selected information from the cellar-book

Graphical representation of triples. The circled numbers are not part of the graphical representation, they are only given here for reference purposes. They correspond to the numbers given in XML comments besides each rdf:Description in Example 7.1 and Example 7.2. The top part of this diagram deals with the RDF while the bottom part deals with the RDF Schema (RDFS) explained in the next section.

Selected information from the cellar-book

All these RDF notations are equivalent, in fact the first thing an RDF parser does when it reads a file, is to transform the information in terms of triples, removing duplicates. The output files are produced by serializing the triples in the same or in another format.

Given the emphasis on XML in this document, we will first focus on the RDF/XML notation. But first, we will explain the concepts with a small set of relations given in the top part of Figure 7.2, the bottom part will be explained in the next section. Example 7.1 gives the corresponding RDF/XML version. As RDF predicates can link any subject and object, an arbitrary network of information can be built which is not necessarily limited to a tree like in XML

As shown in the fourth line of Table 7.1, a triple in RDF/XML, is formed by a rdf:Description element whose content is an element named by the URI of the predicate having the object as content (see line 13‑5 of Example 7.1). By embedding a predicate and its object within a subject, it is easy to regroup triples that share a subject by writing all predicates and their object within the subject element.

A triple can only indicate a binary relation. To indicate an n-ary relation between a subject and n objects, we make use of a blank node (indicated by a circle in Figure 7.2) which is a node with a local URI different from any other one in another file. We first make a relation between the subject and the blank node and then other relations between the blank node and the other objects. For example, to indicate that the cellar-book is located at a given street in a certain city, we first link the cellar-book with a blank node which is then linked to the name of the street and to the name of the city (see the arrow marked by a circled 5 in Figure 7.2).

Components of a triple are URIs which are usually quite long strings many of them varying only at the end within the same file, so it is quite convenient to abbreviate them using entities for the constant part. As the predicates are elements, the constant part can be given as the namespace of the element. A practical way of achieving this is to define an entity and the corresponding namespace prefix with the same letter. As the entity is defined for the whole file, we can also use it for defining the namespace prefix thus ensuring that they always correspond. We use this approach in Example 7.1 at line 3‑2 and line 7‑3. Another way of abbreviating URIs is to make them relative to another one using xml:base, see line 11‑4 of Example 7.1.

An object can either be a URI or a string value. In the latter case, the string is given as the content of the predicate element. The predicate and its string value can also appear as an attribute with its value of the rdf:Description element of the subject (see line 20‑6 of Example 7.1).

Example 7.1. [CBWC-RDF-S.rdf] Subject, Predicate and Object triples for the cellar book in RDF/XML.

Selected information from Example 2.2 coded in RDF/XML. The information was selected to illustrate different features of RDF/XML.

  1 <?xml version="1.0" encoding="UTF-8"?>
    <?oxygen RNGSchema="rdfxml.rnc" type="compact"?>                     (1)
    <!DOCTYPE RDF [                                                      (2)
        <!ENTITY wc "http://www.iro.umontreal.ca/lapalme/WineCatalog#" >
  5     <!ENTITY cb "http://www.iro.umontreal.ca/lapalme/CellarBook" >
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"     (3)
 10          xmlns:cb="&cb;#"
             xml:base="&cb;">                                            (4)
        <rdf:Description                                                 (5)
 15         <cb:ownedBy>                          <!-- 1 -->
                <rdf:Description  rdf:about="&cb;#JudeRaisin"/>
 20     <rdf:Description                                                 (6)
            cb:street="1234 rue des Châteaux" cb:city="St-George"> 
            <cb:named rdf:parseType="Resource">  <!-- 2 -->
 25             <cb:family>Raisin</cb:family>
        <rdf:Description rdf:about="#JudeRaisin"><!-- 3 -->              (7)
 30         <cb:loved rdf:resource="&wc;C00043125"/>
            <cb:loved rdf:resource="&wc;C00871996"/>
            <cb:comment rdf:parseType="Literal">this is <b>great</b>!</cb:comment>
 35     <rdf:Bag rdf:ID="theCellar">             <!-- 4 -->              (8)
            <rdf:li rdf:resource="&wc;C00043125"/>
            <rdf:li rdf:resource="&wc;C00042101"/>
            <rdf:li rdf:resource="&wc;C00871996"/>
        <rdf:Description rdf:about="#theCellar"><!-- 5 -->               (9)
            <cb:locatedAt rdf:nodeID="loc"/>
 45     <rdf:Description rdf:nodeID="loc">      <!-- 6 -->               (10)
            <cb:street>4587 des Futailles</cb:street>
            <cb:city>Vallée des crus</cb:city>
        <!-- Schema definition -->                                       (11)
        <!--   Classes -->
        <rdfs:Class rdf:ID="Person"/>            <!-- 7 -->              (12)
 55     <rdfs:Class rdf:ID="Cellar"/>
        <rdfs:Class rdf:ID="Wine"/>
        <!--   Properties -->
        <rdf:Property rdf:ID="loved">            <!-- 8 -->              (13)
 60         <rdfs:domain rdf:resource="#Person"/>
            <rdfs:range rdf:resource="#Wine"/>
        <rdf:Property rdf:ID="ownedBy">          <!-- 9 -->              (14)
 65         <rdfs:domain rdf:resource="#Cellar"/>
            <rdfs:range rdf:resource="#Person"/>


XML validation can be done using the Relax-NG schema given in appendix A of the RDF definition [78]. Note that this validation only validates the form of the XML file and is different from the schema notion used in RDFS explained in the next section.


Defines two entities to simplify the writing of an URI. wc ends with a # as it will be used to separate fragments within the URI. cb will be used as an URI for a base so it does not end with a #.


Starts an RDF model by setting the appropriate namespaces. rdf must be this one, but the others are application dependant. Here we define two namespaces: wc for the wine-catalog and cb for the cellar-book. Using the entities defined in line 3‑2, it guarantees that predicates using the namespaces and the URI for the identification of the resources are consistent.


Defines the base for relative URI in this document indicated by rdf:ID, such as for line 35‑8. When no xml:base is specified, relative URI use the current document as base. This is useful to shorten the URIs in a RDF document. Note that the base is not used for predicates which must use the namespace prefix.


The cellar-book is owned by the resource identified by JudeRaisin. The straightforward way for noting a triple: both the subject and object are designated by their URI in a rdf:Description element. For illustration purpose, we use here the full URI for the subject and the abbreviated form with an entity for the object. Both notations refer to the same resource as would be one using rdf:ID (see line 29‑7). The predicate is indicated by an element named by its URI using the namespace prefix.


Description of #JudeRaisin with a complex node and attributes. Predicates with a string value can be inserted as attributes of the subject. A predicate with complex content will define a blank node which will act as subject of the content. This fact must be indicated by giving Resource as value of the rdf:parseType attribute.


#JudeRaisin loved two wines of the catalog and expressed this fact by a comment. Predicates can link any two nodes in the graph. The global model is thus an arbitrary graph and not necessarily a tree. To embed XML content as an object, we must specify Literal as value of the rdf:parseType attribute.


The cellar-book, referred by the id CellarBook (corresponding to the full URI given in line 13‑5) contains three wines not further defined in this file. We use a rdf:Bag here instead of a rdf:Description to indicate a container. In a bag, the order of the elements, noted by rdf:li is not important. Should the order be important, we could have used a rdf:Seq. rdf:Alt would indicate an alternative between many cases. The graph representation of a container declaration is a link between the resource and the rdf:bag URI; the rdf:li elements are represented by links denoted by rdf:_n where n is a number corresponding to the order in which the corresponding rdf:li element appeared in the document.


The cellar-book has complex information, so it is regrouped under a blank node referred to by a nodeID which will be defined at line 45‑10. Contrarily to a node referred by a rdf:ID, the id of a blank node, referred by rdf:nodeId is local to this file.


Regrouping the information about the location within a blank node. The string information of the object is given as the value of the predicate element.


Start of the RDFS part that will be further explained in the next section.


Definition of three classes identified with IDs within the namespace identified by the cb entity because of the xml:base declaration. A class declaration is represented in RDF by a rdf:type link between the class name and the predefined rdfs:Class class which is the class of all classes as shown by lines numbered 7 in Figure 7.2.


Defines the loved property linking an instance of a Person class as its domain (i.e. the start of the arrow) with an instance of a Wine class, the range (i.e. the tip of the arrow). These classes were identified in line 54‑12. A property definition also adds a rdf:type link between the name of the property and the predefined rdf:Property (yes, Property is in the rdf namespace and not rdfs).


Defines a ownedBy property linking an instance of a Cellar class with an instance of a Person class.

Although RDF/XML is a convenient triple notation for computers, it is not very user-friendly. So alternatives have been developed, one of the most widespread being the Terse RDF Triple Language more commonly called Turtle [88]. The main rules for writing Turtle triplets are the following:

A blank node of the form _:nodeId can also be noted as [] when the nodeId is not used elsewhere. A blank node as subject such as [] ex:p "o" can be noted as [ex:p "o"]. This type of bracketing can be used in either subject or object position and combined with commas and semi-colons. Table 7.2 compares the bracket notation with the corresponding triples using blank nodes.

Table 7.2. Comparison of Turtle brackets with triples

[] ex:p "o" . _:b0 ex:p "o" .
[ex:p "o"] . _:b1 ex:p "o" .
[ex:p "o"] ex:q ex:o2 . _:b2 ex:p "o".
  _:b2 ex:q ex:o2 .
ex:s ex:p [ex:p1 ex:o]. ex:s ex:p _:b3 .
  _:b3 ex:p1 ex:o .
[ex:p ex:o;ex:p1 "o1"] _:b4 ex:p ex:o .
  _:b4 ex:p1 "o1" .

Comparison between the bracketed notation for blank nodes and the corresponding triples.

Jena [69] provides libraries and a command line tool rdfcopy for parsing and writing RDF triples in different notations, thus providing a simple conversion tool between these notations.

Example 7.2. [CBWC-RDF-S.ttl] The Turtle version of Example 7.1

An easier to type and to read version of the RDF information described in Example 7.1. As before, this section only deals with the RDF part and not the RDFS part starting at line 22‑7. In Turtle, comments start with # and span for the rest of the line. In this example, the numbers in comments correspond to the lines with the same numbers within XML comments in Example 7.1.

  1 @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .     (1)
    @prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix cb:      <http://www.iro.umontreal.ca/lapalme/CellarBook#> .
    @prefix wc:      <http://www.iro.umontreal.ca/lapalme/WineCatalog#> .
    cb:theCellar                                                         (2)
          cb:ownedBy cb:JudeRaisin ;                        # 1
          a       rdf:Bag ;                                 # 4          (3)
          rdf:_1  wc:C00043125 ;
 10       rdf:_2  wc:C00042101 ;
          rdf:_3  wc:C00871996 ;
          cb:locatedAt [ cb:city "Vallée des crus" ;        # 5,6
                         cb:street "4587 des Futailles"] .
 15 cb:JudeRaisin cb:city "St-George" ;                     # 2          (4)
          cb:named [ cb:family "Raisin" ;                                (5)
                     cb:first "Jude" ] ;
          cb:loved wc:C00043125 , wc:C00871996  ;           # 3          (6)
          cb:comment "this is <b>great</b>!"^^rdf:XMLLiteral ;
 20       cb:street "1234 rue des Châteaux" .
    # Schema part in RDFS                                                (7)
    cb:Person a       rdfs:Class .                         # 7           (8)
 25 cb:Cellar a       rdfs:Class .
    cb:Bottle a       rdfs:Class .
    cb:loved                                               # 8           (9)
          a           rdf:Property ;
 30       rdfs:domain cb:Person ;
          rdfs:range  cb:Wine .
    cb:ownedBy                                             # 9           (10)
          a           rdf:Property ;
 35       rdfs:domain cb:Cellar ;
          rdfs:range  cb:Person .


Definition of namespace prefixes. As prefixes can also be used for subjects and objects of triples, which is not the case in RDF/XML, base definition is less useful, but still possible.


Six predicates sharing cb:CellarBook as subject.


The notation for a container in Turtle corresponds to the graphical representation: here, the bag is represented by a link to the predefined rdf:Bag type (a is an abbreviation for rdf:type) followed by links of the form rdf:_n where n is a number indicating the order in which the rdf:li appears in the document. These triples correspond with the arrows with a circled 4 in Figure 7.2.


Four predicates having cb:JudeRaisin as subject are grouped, their predicate and object being separated by semicolons.


A blank node is used as object of cb:named and subject of both cb:family and cb:first, this explains the semi-colon within the square brackets.


Two objects in namespaces wc also share both their subject cb:JudeRaisin and their predicate cb:loved, so they are separated by commas.


Start of the RDFS part further described in the next section.


Definition of three classes in cb namespace. A class declaration is represented in RDF by a a link (which correspond to rdf:type) between the class name and the predefined rdfs:Class class which is the class of all classes as shown by lines numbered 7 in Figure 7.2.


Defines the loved property linking an instance of a Person class as its domain (i.e. the start of the arrow) with an instance of a Wine class, the range (i.e. the tip of the arrow). These classes were identified in line 24‑8. A property definition also adds a a link between the name of the property and the predefined rdf:Property.


Defines a ownedBy property linking an instance of a Cellar class with an instance of a Person class.