RDF JSON Brainstorming

From n² wiki

Jump to: navigation, search

See also: RDF JSON Specification

Note that most of this page is now historical, being an analysis of existing RDF/JSON proposals. The agreed specification is now available on a separate page: RDF JSON Specification. For reference, RDF/JSON looks like this:

{
    "http://example.org/about" : {
        "http://purl.org/dc/elements/1.1/creator" : [ { "value" : "Anna Wilder", "type" : "literal" } ],
        "http://purl.org/dc/elements/1.1/title"   : [ { "value" : "Anna's Homepage", "type" : "literal", "lang" : "en" } ] ,
        "http://xmlns.com/foaf/0.1/maker"         : [ { "value" : "_:person", "type" : "bnode" } ]
    } ,
 
    "_:person" : {
        "http://xmlns.com/foaf/0.1/homepage"      : [ { "value" : "http://example.org/about", "type" : "uri" } ] ,
        "http://xmlns.com/foaf/0.1/made"          : [ { "value" : "http://example.org/about", "type" : "uri" } ] ,
        "http://xmlns.com/foaf/0.1/name"          : [ { "value" : "Anna Wilder", "type" : "literal" } ] ,
        "http://xmlns.com/foaf/0.1/firstName"     : [ { "value" : "Anna", "type" : "literal" } ] ,
        "http://xmlns.com/foaf/0.1/surname"       : [ { "value" : "Wilder", "type" : "literal" } ] , 
        "http://xmlns.com/foaf/0.1/depiction"     : [ { "value" : "http://example.org/pic.jpg", "type" : "uri" } ] ,
        "http://xmlns.com/foaf/0.1/nick"          : [ 
                                                      { "type" : "literal", "value" : "wildling"} , 
                                                      { "type" : "literal", "value" : "wilda" } 
                                                    ] ,
        "http://xmlns.com/foaf/0.1/mbox_sha1sum"  : [ {  "value" : "69e31bbcf58d432950127593e292a55975bc66fd", "type" : "literal" } ] 
    }
}


Contents

[edit] Open Issues

There are a number of open issues that are still being debated:

  • Named graphs: How could named graphs be represented in this format?
  • Media type: application/x-rdf+json or just application/json ?
  • Subject literals: If, and how to express subject Literals (which are allowed in SPARQL turtle, and N3)?

[edit] Named Graphs as Array Properties of Objects

In this proposal graphs are specified an array property of the object.

For example:

{
    "http://example.org/about" : {
        "http://purl.org/dc/elements/1.1/title"   : [ { "value" : "Anna's Homepage", 
                                                        "type" : "literal", 
                                                        "lang" : "en",
                                                        "graphs" : [ "http://example.org/g1", "http://example.org/g2" ]
                                                       } ],
        "http://purl.org/dc/elements/1.1/creator" : [ { "value"  : "Anna Wilder", 
                                                        "type"   : "literal",
                                                        "graphs" : [ "http://example.org/g1" ]
                                                      },
 
                                                      { "value"  : "Andy Wilder", 
                                                        "type"   : "literal",
                                                        "graphs" : [ "http://example.org/g2" ]
                                                      } ]
    }
}

This represents the following two graphs (written in nquads):

<http://example.org/g1> <http://example.org/about> <http://purl.org/dc/elements/1.1/title> "Anna's Homepage" .
<http://example.org/g1> <http://example.org/about> <http://purl.org/dc/elements/1.1/creator> "Anna Wilder" .

and

<http://example.org/g2> <http://example.org/about> <http://purl.org/dc/elements/1.1/title> "Anna's Homepage" .
<http://example.org/g2> <http://example.org/about> <http://purl.org/dc/elements/1.1/creator> "Andy Wilder" .

This has the following advantages:

  1. It's still compact which is the primary reason for using JSON
  2. Triples can explicitly exist in multiple graphs
  3. Backwards compatible with existing triple serialisation
  4. Less duplication since each triple is only mentioned once
  5. Fits main use case of provenence

[edit] Subject Literals using Explicit Types

Not sure if we want to support subject literals but if we do we could use explicit typing as rdfs:Literal. eg:

 "Foo" a rdfs:Literal .


[edit] Historical Analysis

[edit] Design Goals

  • (iand) remove the need for javascript developers to have to parse xml
  • (iand) remove the need for js developers to have to write or find a turtle parser
  • (iand) be able to express all of rdf model
  • (iand) enable rdf to be used for data transfer in AJAX apps
  • (iand) provide some default organisation to the data structure so it isn't just a random list of triples
  • (iand) make it easy to find all the properties of a resource
  • (danja) look simple, so as not to frighten non-RDF developers

[edit] Starting Point

My starting point for this investigation was this set of RDF triples which are representative of the kind of RDF seen commonly out in the wild.

<http://example.org/about> <http://purl.org/dc/elements/1.1/creator> "Anna Wilder" .
<http://example.org/about> <http://purl.org/dc/elements/1.1/title> "Anna's Homepage"@en .
<http://example.org/about> <http://xmlns.com/foaf/0.1/maker> _:person .
_:person <http://xmlns.com/foaf/0.1/homepage> <http://example.org/about> .
_:person <http://xmlns.com/foaf/0.1/made> <http://example.org/about> .
_:person <http://xmlns.com/foaf/0.1/name> "Anna Wilder" .
_:person <http://xmlns.com/foaf/0.1/firstName> "Anna" .
_:person <http://xmlns.com/foaf/0.1/surname> "Wilder" .
_:person <http://xmlns.com/foaf/0.1/depiction> <http://example.org/pic.jpg> .
_:person <http://xmlns.com/foaf/0.1/nick> "wildling" .
_:person <http://xmlns.com/foaf/0.1/nick> "wilda" .
_:person <http://xmlns.com/foaf/0.1/mbox_sha1sum> "69e31bbcf58d432950127593e292a55975bc66fd" .

One of the (many) ways they can be written down as RDF/XML is like this:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:dc="http://purl.org/dc/elements/1.1/">
  <rdf:Description rdf:about="http://example.org/about">
    <dc:creator>Anna Wilder</dc:creator>
    <dc:title xml:lang="en">Anna's Homepage</dc:title>
    <foaf:maker rdf:nodeID="person" />
  </rdf:Description>
  <rdf:Description rdf:nodeID="person">
    <foaf:homepage rdf:resource="http://example.org/about" />
    <foaf:made rdf:resource="http://example.org/about" />
    <foaf:name>Anna Wilder</foaf:name>
    <foaf:firstName>Anna</foaf:firstName>
    <foaf:surname>Wilder</foaf:surname>
    <foaf:depiction rdf:resource="http://example.org/pic.jpg" />
    <foaf:nick>wildling</foaf:nick>
    <foaf:nick>wilda</foaf:nick>
    <foaf:mbox_sha1sum>69e31bbcf58d432950127593e292a55975bc66fd</foaf:mbox_sha1sum>
  </rdf:Description>
</rdf:RDF>

And, for comparison, the same again in Turtle:

@prefix foaf: <http://xmlns.com/foaf/0.1/>
@prefix dc: <http://purl.org/dc/elements/1.1/>
<http://example.org/about>
  dc:creator "Anna Wilder" ;
  dc:title "Anna's Homepage"@en ;
  foaf:maker _:person .

_:person
  foaf:homepage <http://example.org/about> ;
  foaf:made <http://example.org/about> ;
  foaf:name "Anna Wilder" ;
  foaf:firstName "Anna" ;
  foaf:surname "Wilder" ;
  foaf:depiction <http://example.org/pic.jpg> ;
  foaf:nick "wildling" ;
  foaf:nick "wilda" ;
  foaf:mbox_sha1sum "69e31bbcf58d432950127593e292a55975bc66fd" .

There are some common patterns of usage for RDF data. One common thing to want to do is to see the triples associated with a particular subject. Acknowledgement of this common pattern is to be found in SPARQL's describe function and in the notion of concise bounded descriptions. I wanted to keep this approach with my JSON serialisation. I also wanted to borrow the prefixing that Turtle provides so that Javascript code using the JSON structures can retain some semblence of readability. The following JSON is what I cam up with, I'm hoping that it's compact, readable and quite natural to most developers with an apprectiation of RDF.

{
  "prefixes" : {
    "foaf" : "http://xmlns.com/foaf/0.1/" ,
    "dc" : "http://purl.org/dc/elements/1.1/" 
   } ,

  "http://example.org/about" : {
    "dc:creator" : [ { "value" : "Anna Wilder", "type" : "literal" } ] ,
    "dc:title" : [ { "value" : "Anna's Homepage", "type" : "literal", "lang" : "en" } ] ,
    "foaf:maker" : [ { "value" : "_:person", "type" : "bnode" } ]
  } ,

  "_:person" : {
    "foaf:homepage" : [ { "value" : "http://example.org/about", "type" : "uri" } ] ,
    "foaf:made" : [ { "value" : "http://example.org/about", "type" : "uri" } ] ,
    "foaf:name" : [ { "value" : "Anna Wilder", "type" : "literal" } ] ,
    "foaf:firstName" : [ { "value" : "Anna", "type" : "literal" } ] ,
    "foaf:surname" : [ { "value" : "Wilder", "type" : "literal" } ] , 
    "foaf:depiction" : [ { "value" : "http://example.org/pic.jpg", "type" : "uri" } ] ,
    "foaf:nick" : [ { "type" : "literal", "value" : "wildling"} ,  { "type" : "literal", "value" : "wilda" } ] ,
    "foaf:mbox_sha1sum" : [ { "value" : "69e31bbcf58d432950127593e292a55975bc66fd", "type" : "literal" } ] 
  }
}

There are some inherent complexities of the RDF model that don't translate well to any common programming language structure. Repeated properties is always tricky to represent naturally. I've compromised here by making the value of every property an array. Even if the property only has a single value or if it has been declared to be functional elsewhere, it'll still be represented as an array. I feel this is important for consistency of coding. It means that the title of the http://example.org/about page can always be accessed with some Javascript like:

var title = rdf["http://example.org/about"]["dc:title"][0]["value"];

Or, you can find out how many nicknames the person has with an expression like:

var nicks = rdf["_:person"]["foaf:nick"].length


[edit] Serialisation Algorithm

Refer to http://json.org/ for definitions of terminology

  1. Start a JSON object (called the root object)
  2. Create the prefix list:
    1. Determine a suitable list of common prefixes
    2. Create a JSON object for the prefixes list. Each member of the object is a key/value pair where the key is the prefix string and the value is the URI the prefix maps to.
    3. Add a key/value pair to the root object with the key being the string "prefixes" and the value being the prefix object created in the previous step
  3. Group all the triples by subject
  4. For each 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 predicate:
      1. Create a JSON array (called the value array)
      2. Select all triples having the current subject and current predicate
      3. For each value:
        1. Create a JSON object (called the value object)
        2. Add a key/value pair to the value object with the key being the string "value" and the value being the lexical value of the triple value or optionally, in the case of URIs, the prefixed version of the URI
        3. Add a key/value pair to the value object with the key being the string "type" and the value being one of "literal", "uri" or "bnode" depending on the type of the triple's value
        4. If the triple's value is a plain literal and has a language then add a key/value pair to the value object with the key being the string "lang" and the value being the language token
        5. If the triple's value is a typed literal then add a key/value pair to the value object with the key being the string "datatype" and the value being the URI of the datatype or, optionally, the prefixed version of the URI
        6. 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 URI of the predicate or,optionally, the prefixed version of the URI and the value being the value array
    4. Add a key/value pair to the root object with the key being the URI or blank node identifier of the subject and the value being the subject object created in the previous step


[edit] RDF in XOXO

Since every JSON structure can be represented in XOXO, here's what the markup for the above example would look like:

<ol class="xoxo">
  <li>
    <dl>
      <dt>prefixes</dt>
      <dd>
        <dl>
          <dt>foaf</dt>
          <dd>http://xmlns.com/foaf/0.1/</dd>
          <dt>dc</dt>
          <dd>http://purl.org/dc/elements/1.1/</dd>
        </dl>
      </dd>
      <dt>_:person</dt>
      <dd>
        <dl>
          <dt>foaf:depiction</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>uri</dd>
                  <dt>value</dt>
                  <dd>http://example.org/pic.jpg</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:mbox_sha1sum</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>69e31bbcf58d432950127593e292a55975bc66fd</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:name</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>Anna Wilder</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:firstName</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>Anna</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:made</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>uri</dd>
                  <dt>value</dt>
                  <dd>http://example.org/about</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:surname</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>Wilder</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:nick</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>wildling</dd>
                </dl>
              </li>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>wilda</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>foaf:homepage</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>uri</dd>
                  <dt>value</dt>
                  <dd>http://example.org/about</dd>
                </dl>
              </li>
            </ol>
          </dd>
        </dl>
      </dd>
      <dt>http://example.org/about</dt>
      <dd>
        <dl>
          <dt>foaf:maker</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>bnode</dd>
                  <dt>value</dt>
                  <dd>_:person</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>dc:title</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>lang</dt>
                  <dd>en</dd>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>Anna's Homepage</dd>
                </dl>
              </li>
            </ol>
          </dd>
          <dt>dc:creator</dt>
          <dd>
            <ol>
              <li>
                <dl>
                  <dt>type</dt>
                  <dd>literal</dd>
                  <dt>value</dt>
                  <dd>Anna Wilder</dd>
                </dl>
              </li>
            </ol>
          </dd>
        </dl>
      </dd>
    </dl>
  </li>
</ol>

[edit] Other formats

During this investigation I looked at several alternate JSON graph serialisation, which I describe here for reference.

Naively, one can simply convert the N-Triples to an array of hashes where each triple component is represented by an entry in the hash, i.e. "s", "p" and "o":

{
  "data" : [
    { "s" : "<http://example.org/about>", "p" : "<http://purl.org/dc/elements/1.1/creator>", "o" : "Anna Wilder" } ,
    { "s" : "<http://example.org/about>", "p" : "<http://purl.org/dc/elements/1.1/title>", "o" : "Anna's Homepage@en" } ,
    { "s" : "<http://example.org/about>", "p" : "<http://xmlns.com/foaf/0.1/maker>", "o" : "_:person" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/homepage>", "o" : "<http://example.org/about>" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/made>", "o" : "<http://example.org/about>" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/name>", "o" : "Anna Wilder" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/firstName>", "o" : "Anna"  } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/surname>", "o" : "Wilder" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/depiction>", "o" : "<http://example.org/pic.jpg>" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/nick>", "o" : "wildling" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/nick>", "o" : "wilda" } ,
    { "s" : "_:person", "p" : "<http://xmlns.com/foaf/0.1/mbox_sha1sum>", "o" : "69e31bbcf58d432950127593e292a55975bc66fd" } ,
  ]
}

Although capable of representing the full RDF model, this attempt has a serious disadvantage in that the client has to be able to parse the triple components. Inconvenient for the URIs, and annoying for anything more complex such as language literals.

[edit] ARC triples array in PHP structure

A better, but more verbose, approach is to split the triple components up into their distinct data elements. I've based this example on the structure used by ARC, Benjamin Novack's PHP based RDF/XML parser:

{
  "data" : [
    {
      "s" : { "type" : "uri" , "uri" : "http://example.org/about" } ,
      "p" : "http://purl.org/dc/elements/1.1/creator", 
      "o" : { "type" : "literal", "val" : "Anna Wilder" } 
    } ,
    {
      "s" : { "type" : "uri" , "uri" : "http://example.org/about" } ,
      "p" : "http://purl.org/dc/elements/1.1/title", 
      "o" : { "type" : "literal", "val" : "Anna's Homepage", "lang" : "en" } 
    } ,
    {
      "s" : { "type" : "uri" , "uri" : "http://example.org/about" } ,
      "p" : "http://xmlns.com/foaf/0.1/maker", 
      "o" : { "type" : "uri", "uri" : "http://example.org/about#anna" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/homepage", 
      "o" : { "type" : "uri", "uri" : "http://example.org/about" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/made", 
      "o" : { "type" : "uri", "uri" : "http://example.org/about" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/name", 
      "o" : { "type" : "literal", "val" : "Anna Wilder" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/firstName", 
      "o" : { "type" : "literal", "val" : "Anna" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/surname", 
      "o" : { "type" : "literal", "val" : "Wilder" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/depiction", 
      "o" : { "type" : "uri", "uri" : "http://example.org/pic.jpg" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/nick", 
      "o" : { "type" : "literal", "val" : "wildling" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/nick", 
      "o" : { "type" : "literal", "val" : "wilda" } 
    } ,
    {
      "s" : { "type" : "bnode", "bnode_id" : "_:person" } ,
      "p" : "http://xmlns.com/foaf/0.1/mbox_sha1sum", 
      "o" : { "type" : "literal", "val" : "69e31bbcf58d432950127593e292a55975bc66fd" } 
    } 
  ]
}

This definitely works better for the client as there's no additonal parsing needed. However, it's verbose and its bag-like approach to triples means the client will probably need to implement some kind of search capability to find relevant triples. The use of the full URIs everywhere is a bit cumbersome too.

To get Anna's name in this model:

var name = rdf["data"][

[edit] ARC DESCRIBE JSON format

{
 prefixes: {
  rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
  ns0: "http://xmlns.com/foaf/0.1/",
  ns1: "http://semantic-humanities.net/vocabs/pbac/0.1#"
 },
 resources: [

  {
   id: "http://semantic-humanities.net/pbac/#agent-806",
   id_type: "iri",
   properties: {
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
     {
      type: "iri",
      value: "http://xmlns.com/foaf/0.1/Agent"
     }
    ],
    "http://xmlns.com/foaf/0.1/name": [
     {
      type: "literal",
      value: "Ra. Venning"
     }
    ]
   }
  },

  {
   id: "http://semantic-humanities.net/pbac/#agent-936",
   id_type: "iri",
   properties: {
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
     {
      type: "iri",
      value: "http://xmlns.com/foaf/0.1/Agent"
     }
    ],
    "http://xmlns.com/foaf/0.1/name": [
     {
      type: "literal",
      value: "Featlye"
     }
    ]
   }
  },

  {
   id: "http://semantic-humanities.net/pbac/#agent-724",
   id_type: "iri",
   properties: {
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
     {
      type: "iri",
      value: "http://xmlns.com/foaf/0.1/Agent"
     }
    ],
    "http://xmlns.com/foaf/0.1/name": [
     {
      type: "literal",
      value: "Slater"
     }
    ]
   }
  },

  {
   id: "http://semantic-humanities.net/pbac/#agent-1451",
   id_type: "iri",
   properties: {
    "http://semantic-humanities.net/vocabs/pbac/0.1#bio": [
     {
      type: "literal",
      value: "wrote books with John Dod"
     }
    ],
    "http://semantic-humanities.net/vocabs/pbac/0.1#born": [
     {
      type: "literal",
      value: "1561"
     }
    ],
    "http://semantic-humanities.net/vocabs/pbac/0.1#died": [
     {
      type: "literal",
      value: "1625"
     }
    ],
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
     {
      type: "iri",
      value: "http://xmlns.com/foaf/0.1/Agent"
     }
    ],
    "http://xmlns.com/foaf/0.1/name": [
     {
      type: "literal",
      value: "R. Cleaver"
     },
     {
      type: "literal",
      value: "Cleauer"
     },
     {
      type: "literal",
      value: "Cleaver"
     },
     {
      type: "literal",
      value: "Robert Cleaver"
     }
    ]
   }
  },

  {
   id: "http://semantic-humanities.net/names/show?id=1040",
   id_type: "iri",
   properties: {
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
     {
      type: "iri",
      value: "http://xmlns.com/foaf/0.1/Agent"
     }
    ],
    "http://xmlns.com/foaf/0.1/name": [
     {
      type: "literal",
      value: "Jo. Seller"
     }
    ]
   }
  }
 ]
}


[edit] RDF/JSON Platial

see jdil

{
  "@prefix:foaf":"<http://xmlns.com/foaf/0.1/>",
  "@prefix:dc":"<http://purl.org/dc/elements/1.1/>",
 {
  "@about" : "http://example.org/about",
  "dc:creator" : "Anna Wilder",
  "dc:title" : "Anna's Homepage",
  "foaf:maker" : "_:person"
 }, 
 {
  "@about" : "_:person",
    "foaf:homepage" : "http://example.org/about" ,
    "foaf:made" : "http://example.org/about" ,
    "foaf:name" : "Anna Wilder" ,
    "foaf:firstName" : "Anna", "type" ,
    "foaf:surname" : "Wilder", "type" , 
    "foaf:depiction" : "http://example.org/pic.jpg" ,
    "foaf:nick" : { "@values" : [ "wildling", "wilda" ] } ,
    "foaf:mbox_sha1sum" : "69e31bbcf58d432950127593e292a55975bc66fd"  
 }

}

[edit] Triplr

// todo - paste example http://triplr.org/json;pretty/http://sws.geonames.org/5352844/about.rdf

[edit] RDF/JSON Property-Oriented

Using the style of the resource-oriented style, it could look something like this: (rough approximations of JSON!)

 {
  "prefixes" : {
    "foaf" : "http://xmlns.com/foaf/0.1/" ,
    "dc" : "http://purl.org/dc/elements/1.1/" 
   } ,

  "dc:creator" :
   {
   [{ "http://example.org/aboutAW" : "uri",  "Anna Wilder" : "literal"}],
   [{" "http://example.org/aboutJS" : "uri",  "John Smith"  :"literal"}]
   },

  "foaf:maker" :
  {
 ...

But namespace prefixes are only really needed for the properties, so that could be simplified, maybe like:

 {
  "creator" : "http://purl.org/dc/elements/1.1/" 
   {
   [{ "http://example.org/aboutAW" : "uri",  "Anna Wilder" : "literal"}],
   [{" "http://example.org/aboutJS" : "uri",  "John Smith"  :"literal"}]
   },

Also, do we really need to explicitly state the node type, why not just:

 "creator" : "http://purl.org/dc/elements/1.1/" 
   {
    "http://example.org/aboutAW" :  "Anna Wilder",
    "http://example.org/aboutJS" :  "John Smith"   
   }
...

[edit] Exhibit JSON

The json format consumed by SIMILE's Exhibit is a subset of RDF.

http://simile.mit.edu/wiki/Exhibit/Creating%2C_Importing%2C_and_Managing_Data http://simile.mit.edu/wiki/Exhibit/Understanding_Exhibit_Database

a template file

http://simile.mit.edu/wiki/Exhibit/Template/JSON_Data_File

an Exhibit database consists of "types" and "properties" objects, and an array of items. Each item object should contain a label or id property. If multiple items have the same label/id, they are 'smushed' by the Exhibit application.


[edit] Considerations

  • human readability/writability ( flat structures like ["s": '#me',"p": '<http://xmlns.com/foaf/0.1/name>', "o": 'John Smith' ] are rather verbose - it is easier for human authors if resources are packaged into discrete objects )
  • predicatability - programmers should be able to rely on a predictable structure, and be able to write scripts that can use the structure without knowing the contents (which is why it's easier if properties always have an array of values, even if that array consists of only one value).
  • smushability - it should be relatively easy to take multiple rdf/json files and combine the data.

[edit] suggestions

  • put the resource objects in a "resources" object, so that they can be iterated through without having to explicitly ignore the "prefixes" object.

[edit] questions

  • Is the "prefixes" object worth having? source code read/writability can be achieved as easily by declaring constants, and "prefixes" requires the developer to jump through more hoops when 'smushing'.
  • Is it better to have the iri as a key to the resource object, or a property of it? The former provides predictable and quick access to all a resource's properties, the latter allows for resource descriptions to be simply appended to the resources array.

(see irc log of JibberJim and bengee on swig, discussing this)

  • Should resources all be at the same level, or should nesting be allowed, as with RDF/XML. The benefit of having resources at the same level is that it is then easy to access all the resources in the JSON object. The cost (having to check if an object uri identifies a resource in the same json object) is not too onerous.

[edit] Use Cases

  • output from sparql DESCRIBE and CONSTRUCT queries
  • an easy RDF format for scripting languages (like ecmascript,php,python,ruby) to traverse


[edit] further reading


Personal tools