Selecting simple properties from hierarchical JSON

* Despite editing my title by another user, I am looking for a solution that uses the JSON.NET library from C # *

The answer containing psuedocode is wonderful! :)

I am trying to work with hierarchical data provided by a JSON dataset. I am using C # and JSON.NET. I am open to using Linq in general and Linq for JSON.NET in particular if this helps; otherwise, using non-Linq C # / JSON.NET is ok.

Ideally, I try to do two things elegantly:

  • I want to extract the JSON that represents each branch, as well as the branch’s own properties, and not the child (nested) branch objects (I will explain more at some point).

  • I want to track the parent node when I create my branch objects.

For further consideration, please refer to the following JSON excerpt:

{
  "Branch1": {
    "Prop1A" : "1A",
    "Prop1B" : "1B",
    "Prop1C" : "1C",
    "Branch2" : {
      "Prop2A" : "2A",
      "Prop2B" : "2B",
      "Prop2C" : "2C",
      "Branch3" : {
        "Prop3A" : "3A",
        "Prop3B" : "3B",
        "Prop3C" : "3C"
      }
    }
  }
}

Related to Goal 1 (top): Given the JSON consisting of nested JSON objects, I want to highlight only simple (string) properties for each branch. For example, I would like to extract JSON for Branch1, which will only contain the properties Prop1A, Prop1B and Prop1C. Then I would like to extract the JSON for Branch2, which will only contain the properties Prop2A, Prop2B and Prop2C, etc. I understand that I can represent all JSON as a JSON.NET JToken object and then iterate through Children () and look only for JTokenType.Property types, but there may be a more elegant way to quickly select only property types using Linq. ..? In the end, I would have three separate JSON objects that look like this:

JSON Object 1:

{
  "Prop1A" : "1A",
  "Prop1B" : "1B",
  "Prop1C" : "1C"
}

JSON 2 object:

{
  "Prop2A" : "2A",
  "Prop2B" : "2B",
  "Prop2C" : "2C"
}

JSON 3:

{ "Prop3A": "3A", "Prop3B": "3B", "Prop3C": "3C" }

2 (): JSON , . , JSON :

{
  "Prop1A" : "1A",
  "Prop1B" : "1B",
  "Prop1C" : "1C",
  "Parent" : ""
}

{
  "Prop2A" : "2A",
  "Prop2B" : "2B",
  "Prop2C" : "2C",
  "Parent" : "Branch1"
}

:

{
  "Prop3A" : "3A",
  "Prop3B" : "3B",
  "Prop3C" : "3C",
  "Parent" : "Branch2"
}

?

+5
1

JContainer.DescendantsAndSelf(), JSON, properties , value JValue . , List<JObject>, , :

var root = (JContainer)JToken.Parse(jsonString);

var query1 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
             let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
             where l.Any()                                              // Skip objects with no properties
             select new JObject(l);                                     // And return a JObject

var list1 = query1.ToList();

, , JContainer.Descendants(). , ( ), JToken.Type:

             let l = o.Properties().Where(p => p.Value.Type == JTokenType.String)       // Select their string-valued properties

, "", , , JToken.Ancestors:

var query2 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
             let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
             where l.Any()                                              // Skip objects with no properties
             // Add synthetic "Parent" property
             let l2 = l.Concat(new[] { new JProperty("Parent", o.Ancestors().OfType<JProperty>().Select(a => a.Name).FirstOrDefault() ?? "") })
             select new JObject(l2);                                    // And return a JObject.

var list2 = query2.ToList();

, , , . , :

var query3 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
             let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
             where l.Any()                                              // Skip objects with no properties
             // Add synthetic "Parent" property
             let l2 = l.Concat(new[] { new JProperty("Parent", o.Ancestors().OfType<JProperty>().Skip(1).Select(a => a.Name).FirstOrDefault() ?? "") })
             select new JObject(l2);                                    // And return a JObject.

var list3 = query3.ToList();

, :

Console.WriteLine(JsonConvert.SerializeObject(list3, Formatting.Indented));

, , JObject :

[
  {
    "Prop1A": "1A",
    "Prop1B": "1B",
    "Prop1C": "1C",
    "Parent": ""
  },
  {
    "Prop2A": "2A",
    "Prop2B": "2B",
    "Prop2C": "2C",
    "Parent": "Branch1"
  },
  {
    "Prop3A": "3A",
    "Prop3B": "3B",
    "Prop3C": "3C",
    "Parent": "Branch2"
  }
]

, JSON "Parent", JObject .

+4

Source: https://habr.com/ru/post/1648871/


All Articles