Linq-To-JSON query to find the siblings of a particular property in a hierarchical JSON structure
c#, json, json.net, linq
Solution
Here's how I would do it:
JObject jo = JObject.Parse(json);
var props = jo.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "SPECIAL" && (string)p.Value == "QQ01")
.Take(1)
.Select(p => p.Parent)
.SelectMany(o => o.Children<JProperty>())
.Where(p => p.Value.Type == JTokenType.String)
.ToList();
foreach (JProperty prop in props)
{
Console.WriteLine(prop.Name + ": " + prop.Value);
}
Fiddle: https://dotnetfiddle.net/nvIXkO
Problem
Given the following JSON: ``` { "Data": { "SPECIAL": "QQ01", "AA": "QQ", "BB": "QQ", "Data": [ { "SPECIAL": "QQ02", "AA": "QQ", "BB": "QQ", "CC": "QQ", "Data": [ { "SPECIAL": "QQ03", "AA": "QQ", "CC": "QQ", "Data": [ { "SPECIAL": "QQ04", "AA": "QQ", "CC": "QQ", "Data": [ { "SPECIAL": "QQ05", "AA": "QQ", "CC": "QQ", "Data": [ { "SPECIAL": "QQ06", "AA": "QQ", "CC": "QQ" } ] }, { "SPECIAL": "QQ07", "AA": "QQ", "CC": "QQ", "DD": "QQ", "Data": [ { "SPECIAL": "QQ08", "AA": "QQ", "CC": "QQ", "Data": [ { "SPECIAL": "QQ09", "AA": "QQ", "BB": "QQ", "CC": "QQ" } ] } ] } ] } ] } ] } ] } } ``` I thought I understood that a JSON property is simply a name/value pair, where the name is a string and the value can be a string, a JArray, or an JObject. If I am correct, my sample JSON above opens with a Data JObject that contains 3 sibling properties: SPECIAL, AA, and BB. Observe that the next Data entry is a JArray. The array's first element contains an object that has 4 properties: SPECIAL, AA, BB, and CC. QUESTION: How would I issue a Linq query to return the sibling properties for SPECIAL equal to QQ01? The return value should be a List of JProperty containing only: SPECIAL:QQ01, AA:QQ, and BB:QQ. Notice that these properties are in a JObject. The same query would need to work if I want the 4 sibling properties for SPECIAL equal to QQ02. In that case, the return value would be a List of JProperty containing only: SPECIAL:QQ02, AA:QQ, BB:QQ, and CC:QQ. Notice that these properties are in a JObject that's in a JArray. Oh, if there is more than one entry with SPECIAL equal to QQ01 or, in the second case, with SPECIAL equal to QQ02--then I would want only the first. Thank you.