peter
peter

Reputation: 2103

Convert JSON array to XML

I'm trying to convert JSON to XML. My JSON contains an array of cars and each car has an array of features:

[
    {
        "car": {
            "features": [{
                "code": "1"
            }, {
                "code": "2"
            }]
        }
    },
    {
        "car": {
            "features": [{
                "code": "3"
            }, {
                "code": "2"
            }]
        }
    }
]

I'm converting this to XML:

// the tag name for each top level element in the json array
var wrappedDocument = string.Format("{{ car: {0} }}", jsonResult);
// set the root tag name
return JsonConvert.DeserializeXmlNode(wrappedDocument, "cars");

This is the resulting XML:

<cars>
   <car>
      <features>
        <code>1</code>
      </features>
      <features>
        <code>2</code>
      </features>
   </car>
   <car>
      <features>
        <code>3</code>
      </features>
      <features>
        <code>2</code>
      </features>
   </car>
</cars>

My problem is that I would like to have all "features" listed under a common element just like "car" is listed under "cars" so that the XML would look like this:

<cars>
   <car>
       <features>
          <feature>
            <code>1</code>
          </feature>
          <feature>
            <code>2</code>
          </feature>
        </features>
   </car>
   <car>
       <features>
          <feature>
            <code>3</code>
          </feature>
          <feature>
            <code>2</code>
          </feature>
        </features>
   </car>
</cars>

Is that possible using Newtonsoft Json.NET? Thank you for any help!

Upvotes: 7

Views: 12913

Answers (2)

Cinchoo
Cinchoo

Reputation: 6322

With Cinchoo ETL - an open source library, you can do the Xml to Json easily with few lines of code

string json = @"
[
    {
        ""car"": {
            ""features"": [{
                ""code"": ""1""
            }, {
                ""code"": ""2""
            }]
        }
    },
    {
        ""car"": {
            ""features"": [{
                ""code"": ""3""
            }, {
                ""code"": ""2""
            }]
        }
    }
]";
StringBuilder sb = new StringBuilder();
using (var p = ChoJSONReader.LoadText(json))
{
    using (var w = new ChoXmlWriter(sb)
        .Configure(c => c.RootName = "cars")
        //.Configure(c => c.IgnoreRootName = true)
        .Configure(c => c.IgnoreNodeName = true)
        )
    {
        w.Write(p);
    }
}
Console.WriteLine(sb.ToString());

Output:

<cars>
  <car>
    <features>
      <feature>
        <code>1</code>
      </feature>
      <feature>
        <code>2</code>
      </feature>
    </features>
  </car>
  <car>
    <features>
      <feature>
        <code>3</code>
      </feature>
      <feature>
        <code>2</code>
      </feature>
    </features>
  </car>
</cars>

Checkout CodeProject article for some additional help.

Disclaimer: I'm the author of this library.

Upvotes: 0

Brian Rogers
Brian Rogers

Reputation: 129687

DeserializeXmlNode() doesn't really have a way to customize the way it does its JSON to XML conversion. To get the result you want using that method, you will either have to manipulate the JSON before converting it to XML, or manipulate the XML afterwards.

In this case, I think it might be easier to use Json.Net's LINQ-to-JSON API to build the XML directly from the JSON in the shape you want. You can do it like this:

var ja = JArray.Parse(jsonResult);
var xml = new XDocument(
    new XElement("cars", 
        ja.Select(c => 
            new XElement("car",
                new XElement("features", 
                    c["car"]["features"].Select(f => 
                        new XElement("feature", 
                            new XElement("code", (string)f["code"])
                        )
                    )
                )
            )
        )
    )
);

Console.WriteLine(xml.ToString());

Fiddle: https://dotnetfiddle.net/fxxQnL

Upvotes: 2

Related Questions