This code is inside a larger Linq query that iterates through all JArray and all JObject objects that descend from a root JSON object.

My question has to do with

p.SelectToken("COMPANY")

. What this appears to be doing is looking at the ancestor tree at the parent JSON and grabbing the VALUE of the first or default token it sees with a name of "COMPANY". This does exactly what I need it to do. But I have two additional requirements now:

I know that any token with the name "COMPANY" always will map to a string value.

I need to grab the sibling string-value JProperty objects that go along with COMPANY.

to find the first ancestor token that contains a "COMPANY" entry--but then I need to build a List containing all sibling JProperty values, so that the List contains these JProperty elements:

"COMPANY":"Microsoft"
"LOCATION":"Seattle"
"PHONE":"800-555-1212"

Back to p.SelectToken in the lambda expression for Select. I don't know enough about Linq or the various JSON.NET methods to know which method to use other than SelectToken in order to select all of the sibling properties that sit in the same object as the selected token. I tried using a

.Where

with a lambda of

(jt => (jt.Type == JTokenType.JProperty)

and then using a

.Select

with a lambda of

(p => p.Name == "COMPANY")

, but this always produced 0 results. I am just lost. The only thing I can figure is that maybe the solution requires more than an update to the lambda expression, such as a full function with additional variables, etc.

Also, I couldn't find any good documentation at JSON.NET for SelectToken. I just see a simple example and a sentence about what it does. If there are other resources for learning about such JSON.NET Linq methods, please share.

var firstOrDefault = parent
// Walk up the hierarchy
.AncestorsAndSelf()
// Find an object of type JObject
.OfType<JObject>()
// That has a COMPANY property
.Where(o => o["COMPANY"] != null)
// Make a new JObject with the string properties of that JObject
.Select(o => new JObject(o.Properties().Where(p => p.Value.Type == JTokenType.String)))
// And return the first (lowest) one.
.FirstOrDefault();