Путаница в методе Linq-to-JSON SelectToken и альтернативы

Я надеюсь, что смогу задать этот вопрос, не предоставив пример кода, потому что это больше о недостающей документации и потенциальных альтернативных методах / командах.

В моем существующем коде Linq-to-JSON у меня есть этот фрагмент:

var firstOrDefault = parent.AncestorsAndSelf()
    .Select(p => p.SelectToken("COMPANY"))         
    .FirstOrDefault(k => k != null);          

Этот код находится внутри большого запроса Linq, который выполняет итерацию по всем объектам JArray и всем объектам JObject, которые происходят от корневого объекта JSON.

Мой вопрос касается p.SelectToken("COMPANY"), Кажется, что это делает, смотрит на дерево предков родительского JSON и получает ЗНАЧЕНИЕ первого токена или токена по умолчанию, который он видит, с именем "КОМПАНИЯ". Это именно то, что мне нужно. Но теперь у меня есть два дополнительных требования:

  1. Я знаю, что любой токен с именем "КОМПАНИЯ" всегда будет соответствовать строковому значению.
  2. Мне нужно взять одноуровневые объекты JProperty со строковым значением, которые идут вместе с КОМПАНИЕЙ.

Таким образом, у меня может быть фрагмент JSON, который выглядит так:

{
  "COMPANY":"Microsoft",
  "LOCATION":"Seattle",
  "PHONE":"800-555-1212"
  "METADATA" :
  {
     "AA":"AA",
     "BB":"BB"
  }
}

В этом примере я хотел бы использовать p.SelectToken чтобы найти первый маркер-предок, который содержит запись "COMPANY", но затем мне нужно построить список, содержащий все родственные значения JProperty, чтобы список содержал следующие элементы JProperty:

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

Вернуться к p.SelectToken в лямбда-выражении для выбора. Я не знаю достаточно о Linq или различных методах JSON.NET, чтобы знать, какой метод использовать, кроме SelectToken, чтобы выбрать все родственные свойства, которые находятся в том же объекте, что и выбранный токен. Я пытался с помощью .Where с лямбда из (jt => (jt.Type == JTokenType.JProperty) а затем с помощью .Select с лямбда из (p => p.Name == "COMPANY"), но это всегда давало 0 результатов. Я просто потерян. Единственное, что я могу понять, это то, что, возможно, для решения требуется нечто большее, чем обновление лямбда-выражения, например полная функция с дополнительными переменными и т. Д.

Кроме того, я не смог найти хорошую документацию в JSON.NET для SelectToken. Я просто вижу простой пример и предложение о том, что он делает. Если есть другие ресурсы для изучения таких методов JSON.NET Linq, пожалуйста, поделитесь.

1 ответ

Решение

Я считаю, что это должно делать то, что вам нужно:

    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();
Другие вопросы по тегам