使用 JSON 路径编辑 JSON

Editing JSON using JSONPath

你好 SO 社区 :)!

我想创建一种方法,让用户可以编辑(或添加)JSON 特定值或对象(位于 JSON 中的 JSON 路径)。下面的简单示例是我的想法。用户总是输入 JSON、JSONPath 和 value/object 进行更改。我正在使用 Json.NET 库。

方法输入 {json, json路径, valuetoedit} || 输出 {新json作为字符串}

示例输入:

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

示例JSON路径:

$.store.book[*].author

要更改的示例值:

NewAuthorSpecifiedByUser

Output - 新 JSON 其中所有作者都将更改为 'NewAuthorSpecifiedByUser'.

这可能吗?

第 3 方包 可以轻松完成此操作:

  1. 将JSON解析为LINQ to JSON hierarchy of JToken个标记。

  2. Select JSON 要通过 SelectTokens using a query string in JSONPath syntax.

  3. 修改的值
  4. 使用JToken.Replace() replace the selected values with the new values. A new value can be serialized directly to a JToken using JToken.FromObject().

因此:

public static class JsonExtensions
{
    public static JToken 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 root;
    }    

    public static string ReplacePath<T>(string jsonString, string path, T newValue)
    {
        return JToken.Parse(jsonString).ReplacePath(path, newValue).ToString();
    }    
}

然后像这样使用它:

var newJsonAuthorString = JsonExtensions.ReplacePath(jsonString, @"$.store.book[*].author", "NewAuthorSpecifiedByUser");

原型fiddle。如果您要允许用户进行一系列编辑,将 JSON 永久保留在 JToken 层次结构中可能会更有效,而不是反复转换字符串表示形式。

另见 How to install JSON.NET using NuGet?