-1

Using NewtonSoft JSON - We get a JSON File which can consist of both Singular Objects and Arrays (example below). For each Object and each Array we need to parse and enter into separate Datatable. We can also get separate JSON files for each Singular Object and each Array. This we can do. BUT - for the "All in One" - first thing we need to do is detect if the first JSON read - is a "All In One JSON File". If yes, then we need to perform the parsing of each Singular Object into it's DT and also each Array and it's value into a DT. Is this something to do by stepping thru line by line and detecting Token Type? and then performing base on that? Seems like there should be a faster way. NOTE: we don't know the Array Name...they will be dynamic - meaning not every Combine JSON file will include ALL Array's per the Schema. Some could be left out.

Looking for the best and most efficient way of doing the Combine JSON file parsing to DT

JSON Example:

{
  "$schema": "https://abc.def.bay/schema-v1-0-0.json",
  "THISID": "2023",
  "THIS_status_date": "2023-03-30",
  "Array01": [
    {
      "This_ID": "1",
      "title": "Proj",
      "level": 1,
      "type": "typeA",
      "That_ID": "1",
      "Person": "Smith, John",
      "where": "N",
      "when": "Exit 1",
      "why": "Because"
    },
    {
      "This_ID": "2",
      "title": "Proj",
      "level": 1,
      "type": "typeB",
      "That_ID": "2",
      "Person": "Jones, Kelley",
      "where": "N",
      "when": "Exit 2",
      "why": "Because"
    }
  ],
  "Array2": [
    {
      "This_ID": "1",
      "title": "Title A",
      "level": 1,
      "where": "N",
      "why": "Because"
    },
    {
      "This_ID": "2",
      "title": "Title B",
      "level": 2,
      "BelongTo": "1",
      "where": "N",
      "why": "Because"
    }
  ],
midnite11
  • 81
  • 1
  • 10
  • Absolutely not clear what the problem is. Do you need to extract data or what? Where is your DTO? What a Singular Object means? – Serge Jul 17 '23 at 23:26
  • @schema, THISID and THIS_status_date are "singular". Meaning there is only ONE record as opposed to the Array's which can have many records. Yes, I need to extract data. Ideally it would be great to detect the count of Array's....then we know it is ONE Combined JSON file with both Singular's and Array's. Otherwise each Singular's and each Array's would be in their own JSON File. That is the way this customer has designed/organized their JSON output options. – midnite11 Jul 17 '23 at 23:41
  • Using NewtonSoft and knowing it is an Array - is pretty simple to create a DataTable. Seems like a Singular however needs a Class Create to reference. No problem on either, we just are looking for the most efficient way to dissect this Combined JSON file for a Singular - then do this or an Array - then do that kind of thing – midnite11 Jul 17 '23 at 23:42
  • This is not our design. We are just trying to ingests the JSON data efficiently without knowing upfront whether is is one Combined File. And it if is the Combined File, not knowing which Singular's will be included and which Array's will be included. – midnite11 Jul 17 '23 at 23:45
  • Agree your problem is unclear, please try to [edit] your question for clarity. In particular if you are stuck at some point in your code, please share a [mcve] showing where you are stuck. See [ask]. – dbc Jul 17 '23 at 23:59
  • All that being said, if you are trying to deserialize a property whose value is sometimes a single object, and sometimes an array of objects, see [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/q/18994685/3744182). – dbc Jul 17 '23 at 23:59
  • 1
    Let's try this. A Json file has, let's say, 20 different Arrays. Using Newtonsoft, how to iterate thru each array. Like: foreach Array in json.Arrays - detect the Array name, then save that Array to Datatable, next Array. – midnite11 Jul 18 '23 at 01:07
  • @midnite11 please reflect it in question description. because description is misleading – Power Mouse Jul 19 '23 at 12:16

1 Answers1

0

UPDATED. i replace my answer with different parsing approach

void Main()
{
    string json = "{\"$schema\":\"https://abc.def.bay/schema-v1-0-0.json\",\"THISID\":\"2023\",\"THIS_status_date\":\"2023-03-30\",\"Array01\":[{\"This_ID\":\"1\",\"title\":\"Proj\",\"level\":1,\"type\":\"typeA\",\"That_ID\":\"1\",\"Person\":\"Smith, John\",\"where\":\"N\",\"when\":\"Exit 1\",\"why\":\"Because\"},{\"This_ID\":\"2\",\"title\":\"Proj\",\"level\":1,\"type\":\"typeB\",\"That_ID\":\"2\",\"Person\":\"Jones, Kelley\",\"where\":\"N\",\"when\":\"Exit 2\",\"why\":\"Because\"}],\"Array2\":[{\"This_ID\":\"1\",\"title\":\"Title A\",\"level\":1,\"where\":\"N\",\"why\":\"Because\"},{\"This_ID\":\"2\",\"title\":\"Title B\",\"level\":2,\"BelongTo\":\"1\",\"where\":\"N\",\"why\":\"Because\"}]}";

    var jobj = JObject.Parse(json);
    foreach (JProperty content in jobj.Children().ToList())
    {
        // or can filter by type if(content.Value.GetType() == typeof(JArray))
        //if (content.Name.ToLower().StartsWith("arr"))
        if(content.Value.GetType() == typeof(JArray))
        {
            //can serialize to list
            var ja = JArray.FromObject(content.Value);
            ja.ToObject(typeof(List<Array01>)).Dump(content.Name);
            //now you can add to dictionary of (key,List<>) or do what you need

        }
    }
}


public class Array01
{
    public string This_ID { get; set; }
    public string title { get; set; }
    public int level { get; set; }
    public string type { get; set; }
    public string That_ID { get; set; }
    public string Person { get; set; }
    public string where { get; set; }
    public string when { get; set; }
    public string why { get; set; }
    public string BelongTo { get; set; }
}

enter image description here

Power Mouse
  • 727
  • 6
  • 16
  • as you structured json each list is a unique property. if you want to make a array of arrays of objects you need a different json structure. otherwise parse manually through JObject.Parse(json) and foreach (JToken token in obj.FindTokens("tokenname")) or something – Power Mouse Jul 18 '23 at 19:23
  • I apologize that I am not being clear. First, we are not creating JSON. We are reading/parsing. Second, the JSON that comes our way has both Arrays and what we call "Singletons" - which are objects with one value. Our issue is related to the Arrays. There is a possible list of Array's that could be included, but not all of them will be included in every provided JSON file. We don't know which ones will be included. B Based on the name of the Array - we need to do something different with that Array's data. Most of the example's I see using JObject - is parsing a known Array name. – midnite11 Jul 18 '23 at 19:47
  • What we are looking for is a way to iterate thru the JSON to see WHICH arrays are included - without going thru every single line of the JSON. More like a for each loop. Find the first Array found in the JSON file. Get the name. Now that we know the name, do the appropriate "thing" with the Array's data based on the Array's name. Then, from that point of the Reading of JSON file, jump to the next Array. NOT move to the next line - and check to see if it's an Array. I have not seen any examples that show how to open a JSON file and just move from one Array to the next parsing each one. – midnite11 Jul 18 '23 at 19:56
  • What we are using now, which is working, but not sure it's the most efficient. Using StreamReader (sr). Then: String json = sr.ReadToEnd(). Then: dynamic jsonDict = JsonConvert.DeserializeObject(json). Then: var arr01 = JsonConvert.SerializeObject(jsonDict["Array01"]). Then: dt = JsonConvert.DeserializeObject(arr01) -- Just continue doing this for "Array01" thru "Array35".....if the specific Array is not found the DataTable will be Null. – midnite11 Jul 18 '23 at 20:12
  • @midnite11 i updated my answer based on your comments – Power Mouse Jul 19 '23 at 12:11
  • The "Array01" was just an example. The possible array's are all different names and do not follow any specific string pattern. Using "Starts With". Again, is there not a way with NewtownSoft to walk thru existing array's - Find the first Array, no matter the name - do something with it and it's records, find the next Array, then the next, etc. Without actually moving line by line to detect Token Type. – midnite11 Jul 19 '23 at 13:34
  • i have comment in code to use type to get array if(content.Value.GetType() == typeof(JArray)) – Power Mouse Jul 19 '23 at 14:20
  • Thank you. Will give this a shot. – midnite11 Jul 19 '23 at 17:37
  • 1
    Power Mouse - this was excellent. Thank you for your patience. We were able to make this work. The foreach using the JProperty and object children was were we needed educating. Thank you!! – midnite11 Jul 19 '23 at 20:59