*
*
*
*
*

PLEASE NOTE: This page has been replaced by JSONSerializationRules. The following content is retained for archival purposes only.

*
*
*
*
*

($and/ <==do note remove - switch for preventing MathML interpretation of dollar signs)

About

This page describes a format for serialization of the XDI graph model in JSON.

Motivations/Requirements

Rules

Note: Updated 2012-02-08 to reflect the literal contexts proposal. Note: Updated 2011-04-26 to: a) clarify the literal arc trigger (i.e., "!" by itself and "$!" by itself are relational arcs), and b) add the rule that relational arcs may point to nested XDI graphs (identified as XRI cross-references) which are then serialized as JSON objects. Note: Updated 2011-04-04 to reflect the much simpler new format discussed on the TC mailing list in late March.

Following is the proposed ruleset governing the XDI JSON serialization format. Currently it is expressed using the IETF RFC 3885 requirements keywords. This is preliminary to drafting of a full ABNF specification.

  1. An XDI JSON graph serialization MUST be valid JSON according to RFC 4627.

  2. The graph MUST be serialized as a single top-level JSON object ("root context object").
  3. Every XDI statement in the graph MUST be serialized as a JSON object ("context object") contained within root context object.
  4. For every context object, the string representing the JSON object key MUST consist of the first two segments of the XDI statement, i.e., the XRIs representing the XDI subject and XDI predicate. The key MUST include the forward slash separating the XDI subject and XDI predicate, and MUST NOT include a trailing slash after the XDI predicate.
  5. For every context object, the value MUST be a JSON array.
  6. If the XDI predicate is “!”, then the predicate is a literal arc and the value of the JSON array MUST be interpreted as an XDI literal.
  7. If the XDI predicate is “()”, then the predicate is a contextual arc and the value of the JSON array MUST be an array of strings representing XRIs.
  8. Any other XDI predicate MUST be a relational arc and:
    1. If a value in the array is a string, it MUST be interpreted as an XRI.
    2. If a value in the array is a JSON object, it MUST be interpreted as a nested XDI graph in which all the XRIs MUST be expressed as cross-references.

Example

The following example illustrates an example XDI graph called Simple Properties in the XDI Graph Patterns PDF file. See XdiGraphModel.

{
        "()/()": [
                "=abc"
        ],
        "=abc/()": [
                "+age"
        ],
        "=abc+age/!": [ 
                33
        ],
        "=abc+age/$v": [
                "=abc+age$v!2"
        ],
        "=abc+age/()": [ 
                "$d",
                "$v"
        ],
        "=abc+age$d/!": [
                "2010-10-10T11:12:13Z"
        ],
        "=abc+age$v/()": [
                "!1",
                "!2"
        ],
        "=abc+age$v!1/!": [
                32
        ],
        "=abc+age$v!1/()": [
                "$d"
        ],
        "=abc+age$v!1$d/!": [
                "2010-09-09T10:11:12Z"
        ],
        "=abc+age$v!2/$is": [
                "=abc+age!"
        ]
}

Here is the exact set of XDI statements represented by this serialization. Note that there is exactly one statement per arc in the graph.

()/()/=abc
=abc/()/+age
=abc+age/!/(data:,33)
=abc+age/$v/=abc+age$v!2
=abc+age/()/$d
=abc+age/()/$v
=abc+age$d/!/(data:,2010-10-10T11:12:13Z)
=abc+age$v/()/!1
=abc+age$v/()/!2
=abc+age$v!1/!/(data:,32)
=abc+age$v!1/()/$d
=abc+age$v!1$d/!/(data:,2010-09-09T10:11:12Z)
=abc+age$v!2/$is/=abc+age!

Previous Format

Note: This format has now been superceded by the format above.

Following is the proposed ruleset governing the XDI JSON serialization format. Currently it is expressed using the IETF RFC 3885 requirements keywords. This is preliminary to drafting of a full ABNF specification.

  1. An XDI JSON graph serialization MUST be valid JSON according to RFC 4627.

  2. Every XDI context, beginning with the root context, MUST be serialized as a JSON object ("context object").
  3. A context object MAY be empty.
  4. A non-empty context object MUST contain zero-or-one of the following three keys:
    1. ! for XDI literal statements whose subject is the context and whose object is an XDI literal.

    2. * for XDI relational statements whose subject is the context and whose object is another XDI context.

    3. () for XDI contextual statements whose subject is the context and whose object is an XDI subcontext.

  5. The value of a ! key MUST be a JSON object where the key is an XDI predicate and the value MAY be any native JSON datatype (string, number, boolean, null, array, object).

  6. The value of a * key MUST be a JSON object where the key is an XDI predicate and the value MUST be a JSON array.

  7. The value of a () key MUST be a JSON object where the key is an XDI predicate and the value MUST be a JSON object (nested context object).

  8. To normalize the graph, each predicate of a () key MUST be a single-subsegment XRI. Note that the root context MAY have one or more XDI synonyms (statements with $ as the predicate) whose value is an XRI consisting of more than one subsegment.

Notes

This serialization format simplifies XDI graph traversal because at each context level there are three JSON objects representing the three types of XDI statements: a ! object for literal statements, a * object for reference statements, and a () object for subcontext statements. Only () objects are needed for context traversal. When the code finishes context traversal, it can immediately choose the ! object or the * object depending on the predicate type.

Examples

XDI JSON

The following validates at JSON Lint. Note: Updated 2011-02-09 to use the MetagraphSymbols.

{
    "*": {
        "$": [
            "(=example)" 
        ],
        "$!": [
            "(+person)"
        ]
    },
    "()": {
        "=example": {
            "*": {
                "$": [
                    "=!1234.5678.aaaa.bbbb",
                    "=web*example" 
                ],
                "$!": [
                    "+person" 
                ],
                "+friend": [
                    "=markus",
                    "=mary",
                    "=joejohnson" 
                ] 
            },
            "!": {
                "$d!": "2010-11-12T09:10:11Z",
                "+age!": 33,
                "+vegetarian!": false,
                "+nickname!": "Dude",
                "+colors!": [
                    "red",
                    "blue",
                    "green" 
                ],
                "+vcard!": {
                    "home": [
                        {
                            "label": "Primary Residence",
                            "tel": "+1.111.111.1111",
                            "postal": "11 First Ave" 
                        },
                        {
                            "label": "Secondary Residence",
                            "tel": "+1.222.222.2222",
                            "postal": "22 Secondary St." 
                        } 
                    ] 
                } 
            },
            "()": {
                "+age": {
                    "*": {
                        "$!": [
                            "$int!" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+vegetarian": {
                    "*": {
                        "$!": [
                            "$boolean!" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+nickname": {
                    "*": {
                        "$!": [
                            "$string!" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+friend": {
                    "*": {
                        "$!": [
                            "+person*" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+colors": {
                    "*": {
                        "$!": [
                            "$json$array!" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+vcard": {
                    "*": {
                        "$!": [
                            "$json$object!" 
                        ] 
                    },
                    "!": {
                        "$d!": "2010-11-12T09:10:11Z" 
                    } 
                },
                "+address": {
                    "!": {
                        "+street*1": "12233 Corliss Ave N",
                        "+street*2": "Apt 123",
                        "+city": "Seattle",
                        "+state": "WA",
                        "+postal+code": "98133" 
                    },
                    "()": {
                        "$": {
                            "*": {
                                "$!": [
                                    "+address$" 
                                ] 
                            },
                            "!": {
                                "$d!": "2010-11-12T09:10:11Z" 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    }
}

Equivalent in X3 Simple

The following validates in the XDI Validator. Thanks to Markus for his help debugging the quoting problem.

*
        $
                (=example)
        $!
                (+person)
        =example
                /
                        *
                                $
                                        =!1234.5678.aaaa.bbbb
                                        =web*example
                                $!
                                        +person
                                +friend 
                                        =markus
                                        =mary
                                        =joejohnson
                        !
                                $d!
                                        "2010-11-12T09:10:11Z"
                                +age!
                                        "33"
                                +vegetarian!
                                        "$false"
                                +nickname!
                                        "Dude"
                                +colors!
                                        "[\"red\",\"blue\",\"green\"]"
                                +vcard!
                                        "{\"home\":\[{\"label\": \"Primary Residence\",\"tel\": \"+1.111.111.1111\",\"postal\": \"11 First Ave\"},{\"label\": \"Secondary Residence\",\"tel\": \"+1.222.222.2222\",\"postal\": \"22 Secondary St.\"}]}"
                        ()
                                +age
                                        /
                                                *
                                                        $!
                                                                $int!
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +vegetarian
                                        /
                                                *
                                                        $!
                                                                $boolean!
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +nickname
                                        /
                                                *
                                                        $!
                                                                $string!
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +friend
                                        /
                                                *
                                                        $!
                                                                +person*
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +colors
                                        /
                                                *
                                                        $!
                                                                $json$array!
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +vcard
                                        /
                                                *
                                                        $!
                                                                $json$object!
                                                !
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
                                +address
                                        /
                                                !
                                                        +street*1
                                                                "12233 Corliss Ave N"
                                                        +street*2
                                                                "Apt 123"
                                                        +city
                                                                "Seattle"
                                                        +state
                                                                "WA"
                                                        +postalcode
                                                                "98133"
                                                ()
                                                        $
                                                                /
                                                                        *
                                                                                $!
                                                                                        +address$
                                                                        !
                                                                                $d!
                                                                                        "2010-11-12T09:10:11Z"

Equivalent in X2

This is the same format as above except it eliminates the supertyping layer since it is not needed in X3, which makes it shorter. Note that in this format one { character appears for each context node in the graph, beginning with the root context. Every "level" then consists of the predicate/object pairs in that context, thus the name X2.

{
        $
                (=example)
        $!
                (+person)
        =example
                {
                        $
                                =!1234.5678.aaaa.bbbb
                                =web*example
                        $!
                                +person
                        +friend 
                                =markus
                                =mary
                                =joejohnson
                        $d!
                                "2010-11-12T09:10:11Z"
                        +age!
                                "33"
                        +vegetarian!
                                "$false"
                        +nickname!
                                "Dude"
                        +colors!
                                "[\"red\",\"blue\",\"green\"]"
                        +vcard!
                                "{\"home\":\[{\"label\": \"Primary Residence\",\"tel\": \"+1.111.111.1111\",\"postal\": \"11 First Ave\"},{\"label\": \"Secondary Residence\",\"tel\": \"+1.222.222.2222\",\"postal\": \"22 Secondary St.\"}]}"
                        +age
                                {
                                        $!
                                                $int!
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +vegetarian
                                {
                                        $!
                                                $boolean!
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +nickname
                                {
                                        $!
                                                $string!
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +friend
                                {
                                        $!
                                                +person*
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +colors
                                {
                                        $!
                                                $json$array!
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +vcard
                                {
                                        $!
                                                $json$object!
                                        $d!
                                                "2010-11-12T09:10:11Z"
                        +address
                                {
                                        +street*1
                                                "12233 Corliss Ave N"
                                        +street*2
                                                "Apt 123"
                                        +city
                                                "Seattle"
                                        +state
                                                "WA"
                                        +postalcode
                                                "98133"
                                        $
                                                {
                                                        $!
                                                                +address$
                                                        $d!
                                                                "2010-11-12T09:10:11Z"
}

Old Issues

These issues are retained for reference purposes.

Issues Raised By Bill Barnhill About Earlier Proposals

This list remains so that Bill and the TC can discuss how many of these issues have been addressed by the proposal above.

  1. Properties that are not used in reasoning, annotation properties such as the XDI equivalent to rdfs:label, rdfs:comment. This would be a means of having comments that were programmatically accessible. I had proposed $ann for this.
  2. XDI graph envelope, including an 'id' key whose value identifies the graph being exchanged, and an optional 'base' key whose value is the XRI from which all top level subjects are delegates. If the base is a top level subject in the graph as it would be without a base then a the graph with a base added would have that subject as $. So for example a subject @example+mail in a graph without a base would in a graph with the base @example would be +mail. Not covered except that Drummond said he has a proposal for this that keeps everything in the graph.

  3. String literals have no mechanism for language specification without adding 3 levels of nesting through XDI escaping. Mechanism was suggested where language dollar word is appended to the type. ($a$xsd$string$en)

  4. Non-string literals have no mechanism for typing without adding 3 levels of nesting. This nesting makes the simplified version possible but is also poses a very significant overhead on the uses that require this kind of typing and so require XDI escaping on everything. One such use is semantic reasoning, which in my opinion is one of the defining use case for XDI adoption.
  5. for $a$json$object why have another level of nesting, why not have the JSON object be the value? Also what is some-key, is it specified as a specific string? If not then some users might use it and extend on it, some might not, potentially leading to interop issues.
  6. If you have an array of unsigned ints vs an array of strings there is no way to specify that in XDI escaping as far as I can see from the examples, though perhaps you could add XDI escaping to the elements of the XDI escaped array, for a total of 6 levels of nesting. Each level of nesting not only involves additional parsing overhead but additional object creation and memory use from the new object. This was solved by Drummond, in that the type of elements can be appended to the type of the array (e.g. $a$array$xsd$string or $a$json$array$xsd$string, depending on whether JSON specific part is kept).

  7. The literals supported without escaping are JSON strings, JSON numbers, JSON true/false, JSON null. No support for unsigned ints, short vs int, etc, without 3 levels of nesting.
  8. Multiline strings not supported so for example XML has to be like

"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<Root>\n  <Customer>\n            <Name>A. Datum Corporation</Name>\n    <Item>\n      <Key>0001</Key>\n    </Item>\n    <Item>\n      <Key>0002</Key>\n    </Item>\n    <Item>\n      <Key>0003</Key>\n    </Item>\n    <Item>\n      <Key>0004</Key>\n    </Item>\n  </Customer></Root>"

This is very hard to debug and read. With the support for multiline concatenation this would be

[
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n",
"<Root>\n",
"       <Customer>\n",
"               <Name>A. Datum Corporation</Name>\n",
"    <Item>\n",
"      <Key>0001</Key>\n",
"    </Item>\n",
"    <Item>\n",
"      <Key>0002</Key>\n",
"    </Item>\n",
"    <Item>\n",
"      <Key>0003</Key>\n",
"    </Item>\n",
"    <Item>\n",
"      <Key>0004</Key>\n",
"    </Item>\n",
"  </Customer></Root>"
]

Bill's Notes after 2010-08-13 Telecon

Again, these reflect on earlier proposals, but are left here to check off against the current proposal.

Added comments inline based on the new proposed format. Summary: I like it. It's a natural progression from what I had and what Markus had, and while it does not include literal data typing in the serialization I can see the case for that in the xdi dict. -Bill@2010-10-07

Type values seem to have been eliminated and moved to the XDI dictionary, excepting where type value can be inferred from JSON type. Still a little dicey, but ok I think. We won't have user defined datatypes, but can probably live without that. -Bill@2010-10-07

I still think this should be addressed. I also think a standardized encoding should be chosen for XDI, like was done for N3 - perhaps UTF8? Even if the language of a string is to be shown through the XDI graph I'd still like to see an example of a foreign word with language specified. -Bill@2010-10-07

The consensus on this seems to have gravitated to no explicit typing, which I'm nervous about but can deal with, as mentioned in my recent comment above. -Bill@2010-10-07

I think we can finalize this version, I am +1 to do so as a separate document and submit it immediately as a community draft, etc. -Bill@2010-10-07

So..the lack of multiline strings still bothers me, but it also bothers me about JSON. Too much of a corner case to worry about right now though. -Bill@2010-10-07

XDI Annotations, via things like $ann, can be a separate document and supported feature. Speaking of which..we have no feature discovery/negotiation mechanism and I'd really like to see one. -Bill@2010-10-07

On potential for ambiguous typing, meh. It's there, I can deal with, I don't think it's as big a deal as I did before.

I still think the string checking will be a pain, but it's a pain XDI developers can offload to the JSON parser/serializer developers I think, so not as worried about it now as I was before. -Bill@2010-10-07

From a semantic reasoning point of view we'll either need to say (1) that for datatypes we have a very limited set (String, number, boolean, array of each of the same, more?); or (2) that there are no datatypes per se, but that even a literal can be thought of as a XREF'd URI identifying an XDI data node (e.g. (data:application/x-www-form-urlencoded,This%20is%20a%20blog%20title) ). Not advocating X3 encoding it as such, just saying that from a reasoning perspective everything would be a resource. -Bill@2010-10-07

To sum up...

For me this seems to not meet the motivation of "A syntax that is very easy and fast for machines to parse while retaining the full semantic expressability and addressability of XDI.", but it seems to be getting closer. While I am still worried about whether the final version of the JSON-X format will be compatible with semantic reasoning I was very encouraged by the discussions on the call yesterday. --)

While not what I envisioned, I think this is very close to it and meets the goal of "A syntax that is very easy and fast for machines to parse while retaining the full semantic expressability and addressability of XDI."

I've kept links on the benefits of semantic technologies including semantic reasoning, for reference...

Why is semantic reasoning useful?


CategoryInactive

JsonFormat (last edited 2013-05-03 22:27:59 by joseph)