Newtonsoft обновляет JObject из пути JSON?

Я знаю об использовании функции выбора токенов для передачи пути json. Например:

JObject jObect = JObject.Parse("{some json string}");
JToken jToken = jObject.SelectToken("root.item[0].myProperty"); 

Что я ищу, так это простой способ обновить исходный JObject по заданному пути JSON?

jObject[jsonPath] = "My New Value" 

Очевидно, что для этого требуется ключ объекта, а не путь JSON. Спасибо.


person PMOrion    schedule 08.03.2016    source источник
comment
Связано: см. Редактирование JSON с использованием JSONPath   -  person dbc    schedule 08.03.2016


Ответы (2)


Пути Json (и xpaths в этом отношении) используются для получения элементов из иерархии, а не для их установки. Вам нужно получить родительский объект, используя путь JSON, а затем установить свойство обычными способами.

var parent = jObject.SelectToken("root.item[0]");
parent["myProperty"] = "My New Value";
person Jeff Mercado    schedule 08.03.2016
comment
Хорошая сделка. Я полагаю, что могу разметить путь JSON и вытащить имя свойства, поскольку оно всегда должно быть последним элементом пути. - person PMOrion; 08.03.2016
comment
В системе newtonsoft.json есть функция замены, которая может устанавливать значение непосредственно для токена. - person Thaina; 28.01.2019
comment
Есть ли способ изменить JSON на этом пути таким образом, чтобы создать все отсутствующие токены на пути? Поэтому, когда вы пытаетесь установить root.item[0].myProperty, но существует только корневой объект, он не только устанавливает myProperty, но также сначала создает объект, содержащий это свойство, и массив, содержащий этот объект, и свойство элемента, содержащее это множество. - person Kyle Delaney; 26.02.2020
comment
@KyleDelaney Я не думаю, что это вообще возможно. Если вам нужна эта функциональность, вы определенно можете закодировать ее в методе расширения или что-то в этом роде. Это будет включать в себя синтаксический анализ строки jsonpath, интерпретацию того, что подразумевает каждая часть пути об иерархии объектов, и навигацию/создание объектов по мере их продвижения. Это не должно быть слишком сложно, так как есть очень простые правила. - person Jeff Mercado; 26.02.2020
comment
@Thaina имеет лучший ответ - person triple.vee; 18.05.2021

Я думаю, что @dbc дал хорошее расширение, позволяющее нам обновлять значения объекта json. Его ответ можно найти здесь.

Но я бы поместил здесь решение, которое я сделал с помощью приведенного выше ответа:

public static class JsonExtensions
{
    public static JObject ReplacePath<T>(this JToken root, string path, T newValue)
    {
        if (root == null || path == null)
        {
            throw new ArgumentNullException();
        }

        foreach (var value in root.SelectTokens(path).ToList())
        {
            if (value == root)
            {
                root = JToken.FromObject(newValue);
            }
            else
            {
                value.Replace(JToken.FromObject(newValue));
            }
        }

        return (JObject)root;
    }
}

Что вы можете сделать, используя описанный выше метод, вы можете передать JObject, jsonPath и значение, которое хотите заменить. Итак, в вашем случае метод вызова будет выглядеть так:

var = JObject.Parse("{some json string}");   
var jsonObj = JsonExtensions.ReplacePath(jsonObj,
                                         "$. root.item[0].myProperty",
                                         "My New Value");

Надеюсь, это сработает для вас!

Вы можете найти несколько примеров, которые я добавил в https://dotnetfiddle.net/ZrS2iV.

person S.Mishra    schedule 14.10.2020