JSON.Net Xml Serialization misunderstands arrays

Giving my +1 to Iván Pérez Gómez and providing some code here to support his answer:

Add the required json.net namespace to the root node:

private static void AddJsonNetRootAttribute(XmlDocument xmlD)
    {
        XmlAttribute jsonNS = xmlD.CreateAttribute("xmlns", "json", "http://www.w3.org/2000/xmlns/");
        jsonNS.Value = "http://james.newtonking.com/projects/json";

        xmlD.DocumentElement.SetAttributeNode(jsonNS);
    }

And to add json:Array attribute to elements found by xpath:

private static void AddJsonArrayAttributesForXPath(string xpath, XmlDocument doc)
    {
        var elements = doc.SelectNodes(xpath);



        foreach (var element in elements)
        {
            var el = element as XmlElement;

            if (el != null)
            {

                var jsonArray = doc.CreateAttribute("json", "Array", "http://james.newtonking.com/projects/json");
                jsonArray.Value = "true";
                el.SetAttributeNode(jsonArray);
            }
        }
    }

Here is a sample of a single child node as a json array:

Here is a sample of a single child node as a json array:


I did fix this behavior like this

// Handle JsonConvert array bug
var rows = doc.SelectNodes("//Row");
if(rows.Count == 1)
{
    var contentNode = doc.SelectSingleNode("//List/Content");
    contentNode.AppendChild(doc.CreateNode("element", "Row", ""));

    // Convert to JSON and replace the empty element we created but keep the array declaration
    returnJson = JsonConvert.SerializeXmlNode(doc).Replace(",null]", "]");
}
else
{
    // Convert to JSON
    returnJson = JsonConvert.SerializeXmlNode(doc);
}

It's a bit dirty but it works. I'm still interested in other solutions!


From Json.NET documentation: http://james.newtonking.com/projects/json/help/?topic=html/ConvertingJSONandXML.htm

You can force a node to be rendered as an Array by adding the attribute json:Array='true' to the XML node you are converting to JSON. Also, you need to declare the json prefix namespace at the XML header xmlns:json='http://james.newtonking.com/projects/json' or else you will get an XML error stating that the json prefix is not declared.

The next example is provided by the documentation:

xml = @"<person xmlns:json='http://james.newtonking.com/projects/json' id='1'>
        <name>Alan</name>
        <url>http://www.google.com</url>
        <role json:Array='true'>Admin</role>
      </person>";

Generated output:

{
  "person": {
    "@id": "1",
    "name": "Alan",
    "url": "http://www.google.com",
    "role": [
      "Admin"
    ]
  }
}

Tags:

C#

Json

Json.Net