简体   繁体   中英

Extracting variable data from JSON in C#

I have the following JSON which I need to manipulate into a different JSON format to be consumed by another process. My data is variable to some extent. Here is an example:

{
    "subform_12": {
        "multiline_2": "Subform 1 Long Text",
        "listpicker_5": "High",
        "alpha_1": "SubForm 1 Text"
    },
    "subform_13": {
        "multiline_2": "Subform 2 Long Text",
        "alpha_1": "SubForm 2 Text"
    }
}

The variable part is the name of the json object (eg "subform_13") and the number and content of name pairs per object (eg "multiline_2": "Subform 1 Long Text").

What I need to do is convert each node into its own chunk of json, as in the following format:

{
    "subform_13": [
        [{
                "fieldKey": "multiline_2",
                "value": "Subform 2 Long Text"
            },
            {
                "fieldKey": "alpha_1",
                "value": "SubForm 2 Text"
            }
        ]
    ]
}

Then separately:

    {
    "subform_13": [
        [{
                "fieldKey": "multiline_2",
                "value": "Subform 2 Long Text"
            },
            {
                "fieldKey": "alpha_1",
                "value": "SubForm 2 Text"
            }
        ]
    ]
}

So far I see that I can iterate thru the list as follows:

     var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(
            jsonString,
            new Newtonsoft.Json.JsonSerializerSettings()
            {
                DateParseHandling = Newtonsoft.Json.DateParseHandling.None,
            });

    foreach (var item in json)
    {
       // I can see the "subform_13" and contents here in item , how do I generically extract them?
    }

Any help appreciated.

Here is your Main method augmented with the ability to iterate through all values:

    static void Main(string[] args)
    {
        var json = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,JObject>>(
            jsonString,
            new Newtonsoft.Json.JsonSerializerSettings()
            {
                DateParseHandling = Newtonsoft.Json.DateParseHandling.None,
            });
        foreach (var item in json)
        {
            var key = item.Key; // "subform_12"
            var val = item.Value;
            Console.WriteLine(key+":");
            foreach (var field in val)
            {
                var fieldKey = field.Key; // e.g. "multiline_2"
                var fieldVal = field.Value; // e.g. "Subform 1 Long Text"

                Console.WriteLine($"{fieldKey}={fieldVal.Value<string>()}");                    
            }
            Console.WriteLine();
        }
    }

I am just printing the values out; you would construct your new objects - for example as dynamic - using these values.

The output of my Main is:

subform_12:
multiline_2=Subform 1 Long Text
listpicker_5=High
alpha_1=SubForm 1 Text

subform_13:
multiline_2=Subform 2 Long Text
alpha_1=SubForm 2 Text

Hope it helps.

There are probably more elegant ways using linq, but here's code using a plain old JavaScriptSerializer from System.Web.Extensions.

There is a result dictionary, which you probably don't need if you want each object separated.

The json strings for each object is stored in the allJson list.

Similary, if you want the dictionary objects themselves you could just add seperated to a list during each iteration.

        string s = "{\"subform_12\":{\"multiline_2\":\"Subform 1 Long Text\",\"listpicker_5\":\"High\",\"alpha_1\":\"SubForm 1 Text\"},\"subform_13\":{\"multiline_2\":\"Subform 2 Long Text\",\"alpha_1\":\"SubForm 2 Text\"}}";
        JavaScriptSerializer ser = new JavaScriptSerializer();
        Dictionary<string, object> obj = ser.DeserializeObject(s) as Dictionary<string, object>;

        // combined dictionary of all results
        Dictionary<string, object> result = new Dictionary<string, object>();
        // an intermediary dictionary to house the results of each object
        Dictionary<string, object> separated = new Dictionary<string, object>();

        // a list to hold the json representation of each separate object
        List<String> allJson = new List<string>();
        foreach (KeyValuePair<string, object> src in obj)
        {
            Dictionary<string, object> children = (Dictionary<string, object>)src.Value;
            Dictionary<string, object> t = new Dictionary<string, object>();
            separated = new Dictionary<string, object>();
            List<object> l = new List<object>();
            foreach (KeyValuePair<string, object> child in children)
            {
                t.Add("fieldKey", child.Key);
                t.Add("value", child.Value);
                l.Add(t);
                t = new Dictionary<string, object>();
            }
            separated.Add(src.Key, l.ToArray());
            allJson.Add(ser.Serialize(separated));
            result.Add(src.Key, l.ToArray());
        }

        // final string containing all transformed objects combined.            
        string combined = ser.Serialize(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM