<?xml version="1.0"?>
<!-- vim: set et sw=2 wm=5 fdm=syntax nofen: -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>

<rfc ipr="trust200902" docName="draft-rsalz-jsonx-00.txt">

<front>

  <title abbrev="JSONx">
    JSONx, an XML Encoding for JSON
  </title>

  <author initials="B." surname="Muschett" fullname="Brien Muschett">
    <organization>IBM</organization>
    <address>
      <postal>
        <street>8051 Congress Avenue</street>
        <city>Boca Raton</city> <region>FL</region> <code>33487</code>
        <country>USA</country>
      </postal>
      <phone>+1 561-862-2180</phone>
      <email>muschett@us.ibm.com</email>
    </address>
  </author>

  <author initials="R." surname="Salz" fullname="Rich Salz">
    <organization>IBM</organization>
    <address>
      <postal>
        <street>550 King Street</street>
        <city>Littleton</city> <region>MA</region> <code>01460</code>
        <country>USA</country>
      </postal>
      <phone>+1 978-899-2902</phone>
      <email>rsalz@us.ibm.com</email>
      <uri>https://www.ibm.com/developerworks/mydeveloperworks/blogs/soma/</uri>
    </address>
  </author>

  <author initials="M." surname="Schenker" fullname="Michael Schenker">
    <organization>IBM</organization>
    <address>
      <postal>
        <street>555 Bailey Ave.</street>
        <city>San Jose</city> <region>CA</region> <code>95141</code>
        <country>USA</country>
      </postal>
      <phone>+1 408-463-3907</phone>
      <email>mschenk@us.ibm.com</email>
    </address>
  </author>

  <date month="May" year="2011"/>
  <area>Applications</area>
  <keyword>json</keyword>
  <keyword>xml</keyword>

  <abstract>
    <t>This document specifies a mapping between JSON (RFC 4627) and
      XML. The mapping maintains a high degree of fidelity.
      It is used by several IBM products.</t>
  </abstract>
</front>

<middle>
  <section anchor="introduction" title="Introduction">
    <t>This document specifies a mapping between <xref
        target='RFC4627'>JSON</xref> and
      XML, known as JSONx. The mapping maintains a high degree of
      fidelity. It is used by several IBM products.</t>

    <t>JSONx is specified using the terms from the XML Infoset
      <xref target="REC-xml-infoset"/>, serialized
      as XML 1.0 <xref target="REC-xml"/>.  The Infoset terms "Element
      Information Item," "Attribute Information Item," and "Character
      Information Item," are shortened to "element," "attribute," and
      "characters" respectively.  For example, when this specification uses
      the term "element," it is referring to an Element Information Item,
      and when it uses the term "attribute,"
      it is referring to an Attribute Information Item.</t>
  </section>

  <section anchor="rules" title="Conversion Rules">
    <t>JSON identifiers are represented by the string contents of the
      "name" attribute. Most Unicode characters other than backspace
      (Unicode code point U+0008) and form feed (U+000C) are valid
      within identifiers, as long as they are properly escaped (for
      example, \unnnn). When JSONx is serialized as XML documents,
      character and/or entity references may need to be used for special
      characters. Examples of this include ampersand (U+0026),
      less-then sign (U+003C), and any characters not representable in the
      document's encoding.</t>

    <t>Use of backspace, formfeed, or NUL (U+0000) is undefined.</t>

    <section title="root element">
      <t>The root element is either a &lt;json:object> or a &lt;json:array>
        element with the following namespace declaration:</t>
      <texttable>
        <ttcol>Prefix</ttcol>
        <ttcol>Namespace URI</ttcol>
        <c>json</c>
        <c>http://www.ibm.com/xmlns/prod/2009/jsonx</c>
      </texttable>
      <t>All elements defined in this document are in that namespace.</t>
    </section>

    <section title="object">
      <t>A JSON object becomes a &lt;json:object> element. If the object
        denotes a property within a JSON object, JSONx encodes a name
        attribute whose value is assigned the property name. The child
        elements depend on the properties of the JSON object. To improve
        readability, whitespace characters may be added between child
        elements.
        Object elements are ordered according to their document order.</t>

        <figure><artwork xml:space="preserve"><![CDATA[
{ "Ticker" : "IBM" }

<json:object>
    <json:string name="Ticker">IBM</json:string>
</json:object>
            ]]></artwork></figure>

    </section>

    <section title="array">
      <t>A JSON array becomes a &lt;json:array> element. If the array
        denotes a property within a JSON object, JSONx encodes a name
        attribute whose value is assigned the property name. The child
        elements depend on the values in the array. To improve
        readability, whitespace characters may be added between child
        elements.</t>
      <figure><artwork xml:space="preserve"><![CDATA[
"phoneNumbers": [
    "212 555-1111",
    "212 555-2222"
]

<json:array name="phoneNumbers">
    <json:string>212 555-1111</json:string>
    <json:string>212 555-2222</json:string>
</json:array>
          ]]></artwork></figure>

    </section>

    <section title="boolean">
      <t>A JSON boolean becomes a &lt;json:boolean> element. If the
        boolean denotes a property within a JSON object,
        JSONx encodes a name attribute
        whose value is assigned the property name. The boolean value is
        character data as either true or false.</t>
      <figure><artwork xml:space="preserve"><![CDATA[
"remote": false

<json:boolean name="remote">false</json:boolean>
      ]]></artwork></figure>
    </section>

    <section title="string">
      <t>A JSON string becomes a &lt;json:string> element. If the string
        denotes a property within a JSON object,
        JSONx encodes a name attribute whose value
        is assigned the property name. The string value is character
        data.</t>

      <t>Use of the Unicode code points U+0000, U+0008, and U+000C
        is undefined.</t>

      <figure><artwork xml:space="preserve"><![CDATA[
"name": "John Smith"

<json:string name="name">John Smith</json:string>
      ]]></artwork></figure>

    </section>

    <section title="number">
      <t>A JSON number becomes a &lt;json:number> element. If the
        number denotes a property within a JSON object,
        JSONx encodes a name attribute
        whose value is assigned the property name. The number value is
        character data.</t>

      <figure><artwork xml:space="preserve"><![CDATA[
"height": 62.4

<json:number name="height">62.4</json:number>
      ]]></artwork></figure>

    </section>

    <section title="null">
      <t>JSON value of null becomes a &lt;json:null> element. If the
        null value denotes a property within a JSON object,
        JSONx encodes a name attribute
        whose value is assigned the property name. This element has no
        content.</t>

      <figure><artwork xml:space="preserve"><![CDATA[
"additionalInfo": null

<json:null name="additionalInfo" />
          ]]></artwork></figure>
    </section>

  </section>

  <section title="Extended Example">
    <t>The following example document is a sample of the JSON
      structure.</t>
    <figure><artwork xml:space="preserve"><![CDATA[
{
    "name": "John Smith"
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": 10021,
    },
    "phoneNumbers": [
        "212 555-1111",
        "212 555-2222"
    ],
    "additionalInfo": null,
    "remote": false,
    "height": 62.4,
    "ficoScore": "> 640"
}
      ]]></artwork></figure>

      <t>The following output is the result of the transformed document
          as JSONx.</t>
      <figure><artwork xml:space="preserve"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <json:string name="name">John Smith</json:string>
    <json:object name="address">
        <json:string name="streetAddress">21 2nd Street</json:string>
        <json:string name="city">New York</json:string>
        <json:string name="state">NY</json:string>
        <json:number name="postalCode">10021</json:number>
    </json:object>
    <json:array name="phoneNumbers">
        <json:string>212 555-1111</json:string>
        <json:string>212 555-2222</json:string>
    </json:array>
    <json:null name="additionalInfo" />
    <json:boolean name="remote">false</json:boolean>
    <json:number name="height">62.4</json:number>
    <json:string name="ficoScore">&gt; 640</json:string>
</json:object>
      ]]></artwork></figure>

  </section>

</middle>

<back>
  <references title="Normative References">
    <?rfc include="reference.RFC.4627.xml" ?>
    <reference anchor="REC-xml"
        target="http://www.w3.org/TR/2006/REC-xml-20060816">
      <front>
        <title>Extensible Markup Language (XML) 1.0 (Fourth Edition)</title>
        <author fullname="Francois Yergeau" surname="Yergeau" initials="F.">
          <organization></organization>
        </author>
        <author fullname="Jean Paoli" surname="Paoli" initials="J.">
          <organization></organization>
        </author>
        <author fullname="Tim Bray" surname="Bray" initials="T.">
          <organization></organization>
        </author>
        <author fullname="C. M. Sperberg-McQueen"
            surname="Sperberg-McQueen" initials="C.">
          <organization></organization>
        </author>
        <author fullname="Eve Maler" surname="Maler" initials="E.">
          <organization></organization>
        </author>
        <date year="2006" day="16" month="August"></date>
      </front>
      <seriesInfo name="World Wide Web Consortium Recommendation"
        value="REC-xml-20060816"></seriesInfo>
    </reference>

    <reference anchor="REC-xml-infoset"
        target="http://www.w3.org/TR/2004/REC-xml-infoset-20040204">
      <front>
        <title>XML Information Set (Second Edition)</title>
        <author fullname="John Cowan" surname="Cowan" initials="J.">
          <organization></organization>
        </author>
        <author fullname="Richard Tobin" surname="Tobin" initials="R.">
          <organization></organization>
        </author>
        <date year="2004" day="4" month="February"></date>
      </front>
      <seriesInfo name="World Wide Web Consortium Recommendation"
          value="REC-xml-infoset-20040204"></seriesInfo>
    </reference>

  </references>

  <section title="Schema (not normative)">
    <figure><artwork xml:space="preserve"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://www.ibm.com/xmlns/prod/2009/jsonx"
    elementFormDefault="qualified" attributeFormDefault="unqualified"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://www.ibm.com/xmlns/prod/2009/jsonx">

    <xsd:simpleType name="jsonnumbertype">
        <xsd:restriction base="xsd:token">
            <xsd:pattern value="[-]?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:element name="object" type="tns:anyElement" />
    <xsd:element name="array" type="tns:anyElement" />
    <xsd:element name="string" type="tns:stringElement" />
    <xsd:element name="number" type="tns:numberElement" />
    <xsd:element name="boolean" type="tns:booleanElement" />
    <xsd:element name="null" type="tns:emptyElement" />

    <xsd:complexType name="anyElement">
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded"
                    namespace="##targetNamespace" processContents="strict" />
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" />
    </xsd:complexType>

    <xsd:complexType name="emptyElement">
        <xsd:attribute name="name" type="xsd:string" />
    </xsd:complexType>

    <xsd:complexType name="stringElement">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="name" type="xsd:string" />
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>

    <xsd:complexType name="numberElement">
        <xsd:simpleContent>
            <xsd:extension base="tns:jsonnumbertype">
                <xsd:attribute name="name" type="xsd:string" />
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>

    <xsd:complexType name="booleanElement">
        <xsd:simpleContent>
            <xsd:extension base="xsd:boolean">
                <xsd:attribute name="name" type="xsd:string" />
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>

</xsd:schema>
    ]]></artwork></figure>
  </section>

  <section title="JSONx to JSON Stylesheet (not normative)">
    <t>The following XSLT stylesheet takes a JSONx document as input
      and generates JSON. It is intended as a sample implementation, and
      makes no attempt to be well-behaved if the input is not well-defined.
    </t>

    <figure><artwork xml:space="preserve"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    
    <xsl:output method="text" encoding="utf-8" indent="no"
      media-type="application/json"/>

    <xsl:template name="json:doNameAttr">
       <xsl:if test="local-name(..)!='array' and string-length(@name)>0">
          <xsl:value-of select="concat('&quot;', @name, '&quot;', ':')"/>
       </xsl:if>
    </xsl:template>

    <xsl:template match="json:object">
        <xsl:call-template name="json:doNameAttr"/>
        <xsl:text>{ </xsl:text>
        <xsl:for-each select="*">
           <xsl:apply-templates select="."/>
            <xsl:if test="position() != last()">
                <xsl:text>, </xsl:text>
            </xsl:if>
       </xsl:for-each>
       <xsl:text> }</xsl:text>
    </xsl:template>

    <xsl:template match="json:array">
        <xsl:call-template name="json:doNameAttr" />
        <xsl:text>[ </xsl:text>
        <xsl:for-each select="*">
            <xsl:apply-templates select="." />
            <xsl:if test="position() != last()">
                <xsl:text>, </xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text> ]</xsl:text>
    </xsl:template>

    <xsl:template match="json:string">
        <xsl:call-template name="json:doNameAttr"/>
        <xsl:text>"</xsl:text>
        <!-- XXX Need to replace " with &amp;quot; -->
        <xsl:value-of select="normalize-space()"/>
        <xsl:text>"</xsl:text>
    </xsl:template>

    <xsl:template match="json:number">
       <xsl:call-template name="json:doNameAttr"/>
       <xsl:value-of select="normalize-space()"/>
    </xsl:template>

    <xsl:template match="json:boolean">
       <xsl:call-template name="json:doNameAttr"/>
       <xsl:value-of select="normalize-space()"/>
    </xsl:template>

    <xsl:template match="json:null">
        <xsl:call-template name="json:doNameAttr"/>
        <xsl:text>null</xsl:text>
    </xsl:template>

</xsl:stylesheet>
        ]]></artwork></figure>

  </section>

</back>
</rfc>
