Clone wiki

Manatee.Json / XML

This repository has been migrated to GitHub


Converting JSON to XML and back can be difficult. XML contains features that JSON does not (e.g. attributes), while JSON objects can contain keys that have no formatting restrictions (i.e. any string is valid). For clarity this section begins with the rules which this library follows in order to perform these conversions in a consistent manner. Later, this section will elaborate on how to use this functionality.


  1. All values must be stored as content of an element (except objects, which may be converted into a collection of “root” elements).

    <anotherKey>a string</anotherKey>
  2. JSON Objects

    • The XML value maps to the JSON object value.
    • The XML element name maps to the JSON object key.
    • XML element names will map with the appropriate namespace, aliases preserved.
    • XML elements which do not contain a value map to JSON null.
    <aKey>5</aKey> {"aKey":5}
    <aKey/> {"aKey":null}
  3. JSON Arrays

    • When an XML element name appears more than once, the associated values are collected into a JSON array under a key of that name.
    • Nested arrays must be contained in an element that has a “nest” attribute with a value of “true”.
    • Element names for items in nested arrays must match the name of the parent element.
    <aKey>5</aKey><anotherKey>a string</anotherKey><aKey>false</aKey><aKey nest="true"><aKey/><aKey>true</aKey><aKey nest="true"><aKey>42</aKey></aKey></aKey><aKey nest="true"><aKey><innerKey>-6</innerKey></aKey><aKey/></aKey> {"aKey":[5,false,[null,true,[42]],[{"innerKey":-6},null]],"anotherKey":"a string"}
  4. XML Attributes

    • When attributes exist on XML elements, they must be prefixed with a hyphen ('-') and collected into an object which will then be stored in a JSON array along with the element's value.
    • XML attribute names will map with the appropriate namespace, aliases preserved.
    • Namespace declarations are considered as standard attributes, as they are with the LINQ to XML classes.
    <aKey attrib="true">5</aKey> {"aKey":[{"-attrib":true},5]}
    <aKey xmlns="http://url">5</aKey> {"aKey":[{"-attrib":"http:\/\/url\/"},5]}
  5. Data Type Inference when converting from XML

    • Types will be inferred by default.
    • Types can be explicitly specified by using the “type” attribute.
    • An exception will be thrown if a value cannot be interpreted as the specified type.
    • JSON to XML will make a “best guess” as to whether to place the “type” attribute (ex. If the type is string but properly parses to a boolean or a number).
    • Type inference will also occur on attributes, however attribute types cannot be explicitly specified.
    <aKey>5</aKey> {"aKey":5}
    <aKey type="String">5</aKey> {"aKey":"5"}
    <aKey type="Number">true</aKey> Throws exception
    <aKey attrib="true">5</aKey> {"aKey":[{"-attrib":true},5]}


Microsoft .Net 4.0 provides two ways of interacting with XML objects: XmlNode in the System.Xml namespace, and XElement in the System.Xml.Linq namespace. Although this library natively uses XElement, two extension methods have been provided to change between the two XML objects.

Method Extends Description
ToXElement() System.Xml.XmlNode Converts an XmlNode to an equivalent XElement
ToXmlNode() System.Xml.Linq.XElement Converts an XElement to an equivalent XmlNode

To convert a JsonValue to an XElement, the ToXElement() extension method has been created for JsonValue. The method uses a single parameter which will be used as a root node.

The conversion call requires that a non-null, non-empty, non-whitespace key be submitted to be used a root element. This is due to another fundamental difference between JSON and XML: XML requires a root element, whereas a fully-formed JSON construct is generally a collection of keys without a root name. If an invalid key is passed to the method on a JsonValue of any other type, an ArgumentException exception is thrown. The return value of ToXElement() is a single XElement which contains (either as a value or subelements) the JSON data translated to XML.

JsonValue json = new JsonObject{{"key1", "value"}, {"key2":42}};
var xml = json.ToXElement("root");

This code snippet generates the following XML:


This simple example can be extended simply using the aforementioned rules.

The only instance in which a null key is allowed to be passed to the ToXElement() method is when the JsonValue is a JSON object with a single key/value pair. In this case, the key is used as the root element. If the method is called with a null key on an object with more than one key/value pair, an ArgumentException exception is thrown.

Converting from an XElement to a JsonValue is just as simple. The ToJson() extension method has been created for XElement and IEnumerable<XElement>. These methods have no parameters and will always yield a JsonValue containing a JsonObject. The method for a single XElement will yield a JsonObject with a single key/value pair; the method for a collection of XElements will yield a JsonObject with a key/value pair for each XElement.

var xml = new XElement("root");
var element = new XElement("key1", "value");
element = new XElement("key2", 42);
var json = xml.ToJson();

As expected this code snippet generates the following JSON.


The key feature of these methods is that data can be converted from one format to the other and back, resulting in data that is equivalent to the original.

Home | Architecture | Usage | Serialization | Schema | JSONPath | XML Conversion | Support