Convert XML to JSON and force array with C# Newtonsoft

·

2 min read

Sometime you need to serialize a Xml document to JSON string, and you want some nodes will be serialize as an array always.

Xml document:

<School Name="Havard">
    <Class Name="Math">
        <Student ID="1" Name="John" />
        <Student ID="2" Name="Max" />
        <Student ID="3" Name="Kevin" />
    </Class>
    <Class Name="Chemistry">
        <Student ID="4" Name="Jack" />
    </Class>
</School>

Convert XML to JSON with with C# Newtonsoft:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

string json = JsonConvert.SerializeXmlNode(doc);

Result in JSON string format:

{
"School": {
    "Name": "Havard",
    "Class": [
        {
            "Name": "Math",
            "Student": [
                {"ID": "1", "Name": "John"},
                {"ID": "2", "Name": "Max"},
                {"ID": "3", "Name": "Kevin"}
            ]
        },
        {
            "Name": "Chemistry",
            "Student": {"ID": "4", "Name": "Jack"}
        },
    ]
}

As you can see, if the "Class" has more than 1 student, the "Student" will be an array. But how if we have only 1?

It would be an issue if you need to convert this JSON result to C# object later. So how to fix it?

There we come a solution how to force "Student" in the json string as an array always: by adding "json:Array='true'".

// get parent node by tag name
XmlNodeList classes= xmlDoc.GetElementsByTagName("Class");

    // for each parent node, count its children
    // if count = 1 --> add attribute json:Array='true'
    foreach (XmlNode class in classes)
    {
        var students = class .ChildNodes;

        if (students.Count == 1) // force array here 
        {
            var attribute =
                    xmlDoc.CreateAttribute("json", "Array", "http://james.newtonking.com/projects/json");

            attribute.InnerText = "true";
            var node = nodeChildren.Item(0) as XmlElement;
            node.Attributes.Append(attribute);
        }
    }