'How to add new property in json string by using json path

I want to add a json property (name and value) or json data(array) to existing json string.

User has to specify a json path to specify where to add it.

Can someone help me to provide a link/example to progress on this.

Regards, Amar



Solution 1:[1]

If you want to set a existed place of path, you can use SelectToken:

void SetValueByPath(JToken token, string path, object value)
{
  var newToken = value == null ? null : JToken.FromObject(value);
  var targetToken = token.SelectToken(path);
  if(targetToken.Type == JTokenType.Property)
    targetToken.Replace(newToken)
}

But if you want to set a not existed place of path, here is the code:

//Origin code by Squirrel.Downy(Flithor)
public static void AddTokenByPath(JToken jToken, string path, object value)
{
    // "a.b.d[1]['my1.2.4'][4].af['micor.a.ee.f'].ra[6]"
    var pathParts = Regex.Split(path, @"(?=\[)|(?=\[\.)|(?<=])(?>\.)")
        // > { "a.b.d", "[1]", "['my1.2.4']", "[4]", "af", "['micor.a.ee.f']", "ra", "[6]" }
        .SelectMany(str => str.StartsWith("[") ? new[] { str } : str.Split('.'))
        // > { "a", "b", "d", "[1]", "['my1.2.4']", "[4]", "af", "['micor.a.ee.f']", "ra", "[6]" }
        .ToArray();
    JToken node = jToken;
    for (int i = 0; i < pathParts.Length; i++)
    {
        var pathPart = pathParts[i];
        var partNode = node.SelectToken(pathPart);
        //node is null or token with null value
        if (partNode == null || partNode.Type == JTokenType.Null)
        {
            if (i < pathParts.Length - 1)
            {
                //the next level is array or object
                //accept [0], not ['prop']
                JToken nextToken = Regex.IsMatch(pathParts[i + 1], @"\[\d+\]") ?
                    new JArray() : new JObject();
                SetToken(node, pathPart, nextToken);
            }
            else if (i == pathParts.Length - 1)
            {
                //JToken.FromObject(null) will throw a exception
                var jValue = value == null ?
                   null : JToken.FromObject(value);
                SetToken(node, pathPart, jValue);
            }
            partNode = node.SelectToken(pathPart);
        }
        node = partNode;
    }
    //set new token
    void SetToken(JToken node, string pathPart, JToken jToken)
    {
        if (node.Type == JTokenType.Object)
        {
            //get real prop name (convert "['prop']" to "prop")
            var name = pathPart.Trim('[', ']', '\'');
            ((JObject)node).Add(name, jToken);
        }
        else if (node.Type == JTokenType.Array)
        {
            //get real index (convert "[0]" to 0)
            var index = int.Parse(pathPart.Trim('[', ']'));
            var jArray = (JArray)node;
            //if index is bigger than array length, fill the array
            while (index >= jArray.Count)
                jArray.Add(null);
            //set token
            jArray[index] = jToken;
        }
    }
}

Solution 2:[2]

You can just use Newtonsoft.Json:

        var input = "{ test: true }";

        var jObject = JObject.Parse(input);

        jObject["updated"] = true;
        jObject["array"] = new JArray("item1", "item2", "item3");

        var s = jObject.ToString();

        // { test: true, updated: true, array: ["item1", "item2", "item3"] }
        Console.WriteLine(s);

Above we've parsed the json string in to a JObject then with that JObject we can start to modify it by adding fields etc.. then to get back the string representation we just call ToString on the JObject.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Kevin Smith