skip to Main Content

I have the following XML

<table>
    <name>Table 1</name>
    <headers>
        <header>Header 1</header>
        <header>Header 2</header>
    </headers>
    <data>
        <row>
            <row_item>Item 1</row_item>
            <row_item>Item 2</row_item>
        </row>
        <row>
            <row_item>Item 3</row_item>
            <row_item>Item 4</row_item>
        </row>
    </data>
</table>

Now I can deserialize this easy enough using the built in XmlSerializer class using this class.

[JsonObject("table")]
[XmlRoot("table")]
public class Table
{
    [JsonProperty("name")]
    [XmlElement("name")]
    public string Name { get; set; }

    [JsonProperty("headers")]
    [XmlArray("headers"), XmlArrayItem("header")]
    public List<string> Headers { get; set; } = new List<string>();

    [JsonProperty("data")]
    [XmlArray("data"), XmlArrayItem("row")]
    public List<DataRow> Data { get; set; } = new List<DataRow>();

}

public class DataRow
{
    [XmlElement("row_item")]
    public List<string> DataRowItems { get; set; }
}

Now I need to convert this to JSON, I am using Newtonsoft to do this but the problem I am facing is that the current class structure adds "DataRowItems" to the JSON.

{
    "table": [
        {
            "data": [
                {
                    "DataRowItems": [
                        "Item 1",
                        "Item 2"
                    ]
                },
                {
                    "DataRowItems": [
                        "Item 3",
                        "Item 4"
                    ]
                }
            ],
            "headers": [
                "Item 1",
                "Item 2",
                "Item 3"
            ],
            "name": "Some text"
        }
    ]
}

Where as I need to send the data element as an array of array, like this.

{
  "table": [
    {
      "data": [
        ["Item 1", "Item 2", "Item 3"],
        ["Item 4", "Item 5", "Item 6"]
      ],
      "headers": ["Column 1", "Column 2", "Column 3"],
      "name": "Some text"
    }
  ]
}

How can I achieve this? I have been trying with various XML and JSON attributes but can’t seem to get it to work. I have also tried using List<List> instead of List which creates the JSON correctly, but the XML fails to deseralize.

3

Answers


  1. Chosen as BEST ANSWER

    Thank you everyone for the suggestions, this was the final setup for property in the class that I used to get it working.

        [JsonProperty("data")]
        [XmlArray("data")]
        [XmlArrayItem("row")]
        [XmlArrayItem("row_item", NestingLevel = 1)]
        public List<List<string>> Data { get; set; } = new List<List<string>>();
    

    The NestingLevel item was the key to getting row_item to deserialize correctly.


  2. Remove DataRow and put a nested List this way:

        [JsonObject("table")]
        [XmlRoot("table")]
        public class Table
        {
            [JsonProperty("name")]
            [XmlElement("name")]
            public string Name { get; set; }
    
            [JsonProperty("headers")]
            [XmlArray("headers"), XmlArrayItem("header")]
            public List<string> Headers { get; set; } = new List<string>();
    
            [JsonProperty("data")]
            [XmlArray("data"), XmlArrayItem("row")]
            public List<List<string>> Data { get; set; } = new List<List<string>>();
    
        }
    

    I obtained:
    {"name":"aaa","headers":["H1","H2","H3"],"data":[["i1","i2"],["i3","i4"]]}

    Login or Signup to reply.
  3. you can try this, you don’t need any custom classes

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml);
        
        var json = JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true);
        var jObj = JObject.Parse(json);
    
        jObj["headers"] = jObj["headers"]["header"];
        jObj["data"] = new JArray(jObj["data"]["row"].Select(x => x["row_item"]));
        json=jObj.ToString();
    

    output

    {
      "name": "Table 1",
      "headers": [
        "Header 1",
        "Header 2"
      ],
      "data": [
        [
          "Item 1",
          "Item 2"
        ],
        [
          "Item 3",
          "Item 4"
        ]
      ]
    }
    

    or if you want c# object

    DataClass data = jObj.ToObject<DataClass>();
    
    public partial class DataClass
    {
        [JsonProperty("name")]
        public string Name { get; set; }
    
        [JsonProperty("headers")]
        public List<string> Headers { get; set; }
    
        [JsonProperty("data")]
        public List<List<string>> Data { get; set; }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search