The Resource Description Framework (RDF) is a framework for representing information in the Web.

This document defines a textual syntax for RDF called RDF/JSON that allows an RDF graph to be completely written in a form compatible with the JavaScript Object Notation (JSON) [[!RFC4627]] and alternative to the one recommended in JSON-LD [[JSON-LD]].

The syntax defined in this document should not be used unless there is a specific reason to do so. Use of JSON-LD is recommended.

Important Note: The RDF Working Group has decided not to push this document through the W3C Recommendation Track. You should therefore not expect to see this document eventually become a W3C Recommendation.

This document was published as a Working Group Note to provide those who are using it and/or have an interest in it with a stable reference.

The RDF Working Group decided to put JSON-LD on the Recommendation track. Therefore, unless you have a specific reason to use the syntax defined in this document instead of JSON-LD, you are encouraged to use JSON-LD.

Introduction

This document defines RDF/JSON, a concrete syntax for RDF, as defined in the RDF Concepts and Abstract Syntax W3C Recommendation [[!RDF11-CONCEPTS]], in JavaScript Object Notation (JSON) [[!RFC4627]].

The syntax defined in this document is an alternative to the one recommended in JSON-LD [[JSON-LD]]. It should not be used unless there is a specific reason to do so. Use of JSON-LD is recommended.

Overview of RDF/JSON

An RDF Graph consists of a set of RDF triples, each triple consisting of a subject, a predicate and an object (formally defined in [[!RDF11-CONCEPTS]]). An RDF/JSON document serializes such a set of RDF triples as a series of nested data structures.

A conforming RDF/JSON document consists of a single JSON object called the root object. Each unique subject in the set of triples is represented as a key in the root object. No key may appear more than once in the root object.

The value of each root object key is a further JSON object whose keys are the URIs of the predicates occuring in triples with the given subject. These keys are known as predicate keys. No predicate key may appear more than once within a single object.

The value of each predicate key is an array of JSON objects representing the object of each serialized triple.

In general, a triple (subject S, predicate P, object O) is serialized in the following structure:

{ "S" : { "P" : [ O ] } }

The object of the triple O is represented as a further JSON object with the following keys:

type
one of 'uri', 'literal' or 'bnode' (required)
value
the URI of the object, its lexical value or a blank node label depending on whether the object is a uri, literal or bnode
lang
the language of a literal value (optional but if supplied it must not be empty)
datatype
the datatype URI of the literal value (optional)

Blank node subjects are named using a string conforming to the nodeID production in Turtle. For example: _:A1

The 'lang' and 'datatype' keys should only be used if the value of the 'type' key is "literal".

All keywords defined in this document are case sensitive, and must be lowercase.

Serialization of RDF as JSON

Given a set of RDF Triples an RDF/JSON document may be constructed using the following algorithm:

  1. Start a JSON object (called the root object)
  2. Group all the triples by subject
  3. For each unique subject:
    1. Create a JSON object for the subject (called the subject object)
    2. Group all triples having the current subject by predicate
    3. For each unique predicate:
      1. Create a JSON array (called the value array)
      2. Select all triples having the current subject and current predicate
      3. For each triple:
        1. Create a JSON object (called the value object)
        2. Add the following key/value pairs to the value object:
          • If the object of the triple is an RDF URI Reference U add a key called "type" with a value being the string "uri". Add a key called "value" with the value being U.
          • If the object of the triple is an RDF Literal S add a key called "type" with a value being the string "literal". Add a key called "value" with the value being the lexical form of S and:
            • If the object of the triple is an RDF Literal with language L, add a key called "lang" with the value being L.
            • If the object of the triple is an RDF Typed Literal with datatype URI D, add a key called "datatype" with the value being D.
          • If the object of the triple is a Blank Node with label I add a key called "type" with a value being the string "bnode". Add a key called "value" with the value being the string formed by concatenting an underscore (U+005F) followed by a colon (U+003A) followed by I.
        3. Push the value object onto the end of the value array.
      4. Add a key/value pair to the subject object with the key being the predicate URI and the value being the value array.
    4. Add a key/value pair to the root object with value being the subject object created in the previous step and the key being one of the following:
      • If the subject of the triple is an RDF URI Reference U the key is U.
      • If the subject of the triple is a Blank Node with label I the key is the string formed by concatenting an underscore (U+005F) followed by a colon (U+003A) followed by I.

Examples

An example of a single triple with a literal object having a language of "en"

      {
        "http://example.org/about" : {
            "http://purl.org/dc/terms/title" : [ { "value" : "Anna's Homepage", 
                                                   "type" : "literal", 
                                                   "lang" : "en" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples [[!N-TRIPLES]]:

      <http://example.org/about> <http://purl.org/dc/terms/title> "Anna's Homepage"@en .                                                        
    

An example of two triples that share the same subject and predicate but have differing objects:

      {
        "http://example.org/about" : {
            "http://purl.org/dc/terms/title" : [ { "value" : "Anna's Homepage", 
                                                   "type" : "literal", 
                                                   "lang" : "en" },
                                                 { "value" : "Annas hjemmeside", 
                                                   "type" : "literal", 
                                                   "lang" : "da" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples:

      <http://example.org/about> <http://purl.org/dc/terms/title> "Anna's Homepage"@en .                                                        
      <http://example.org/about> <http://purl.org/dc/terms/title> "Annas hjemmeside"@da .                                                        
    

An example of a triple with a datatyped literal object:

      {
        "http://example.org/about" : {
            "http://purl.org/dc/terms/title" : [ { "value" : "<p xmlns=\"http://www.w3.org/1999/xhtml\"><b>Anna's</b> Homepage>/p>", 
                                                   "type" : "literal", 
                                                   "datatype" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples:

      <http://example.org/about> <http://purl.org/dc/terms/title> "<p xmlns=\"http://www.w3.org/1999/xhtml\"><b>Anna's</b> Homepage>/p>"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral> .
    

An example of triples with a common blank node:

      {
        "http://example.org/about" : {
            "http://purl.org/dc/terms/creator" : [ { "value" : "_:anna", 
                                                     "type" : "bnode" } ] ,
        "_:anna" : {
            "http://xmlns.com/foaf/0.1/name" : [ { "value" : "Anna", 
                                                   "type" : "literal" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples:

      <http://example.org/about> <http://purl.org/dc/terms/creator> _:anna .
      _:anna <http://xmlns.com/foaf/0.1/name> "Anna" .
    

An example of a triple with a URI object:

      {
        "_:anna" : {
            "http://xmlns.com/foaf/0.1/homepage" : [ { "value" : "http://example.org/anna", 
                                                       "type" : "uri" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples:

      _:anna <http://xmlns.com/foaf/0.1/homepage> <http://example.org/anna> .
    

An example of triples with common subjects:

      {
        "_:anna" : {
            "http://xmlns.com/foaf/0.1/name" : [ { "value" : "Anna", 
                                                   "type" : "literal" } ],
            "http://xmlns.com/foaf/0.1/homepage" : [ { "value" : "http://example.org/anna", 
                                                       "type" : "uri" } ] 
        }
      }                                                        
    

This is equivalent to the following N-Triples:

      _:anna <http://xmlns.com/foaf/0.1/name> "Anna" .
      _:anna <http://xmlns.com/foaf/0.1/homepage> <http://example.org/anna> .
    

An empty RDF graph is serialized as a JSON object with zero keys.

{ }

Acknowledgments

This document is based on original work from Talis [[TALIS-RDF-JSON]] and has benefited from the review of the RDF WG, especially Andy Seaborne and Pierre-Antoine Champin.

Internet Media Type, File Extension and Macintosh File Type

The suggested media type for RDF/JSON is "application/rdf+json".

It is suggested that RDF/JSON files have the extension ".rj" (all lowercase) on all platforms.

JSON is encoded in Unicode, with a default encoding of UTF-8. See RFC627, section 3 "Encoding".