深度查找或搜索 JSON 中任何级别的键并替换其在 C# 中的值

2024-01-27

我也被一个问题所困扰。我能够将嵌套的 JSON 转换为 key-Value ,但现在我想将其转换回原来的 json 格式。由于我的问题,我无法使用 C# 对象模型来执行此操作,因为我拥有的 JSON 文件是动态的,并且其结构会随着时间的推移而变化。所以我正在寻找解决方案,通过它我们可以通过更新的键值对序列化和反序列化 JSON。任何帮助都会让人如释重负。 TIA。

JSON 代码示例:

 {
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 25,
  "address": {
  "streetAddress": "21 2nd Street",
  "city": "New York",
  "state": "NY",
  "postalCode": "10021-3100"
 },
"phoneNumbers": [
{
  "type": "home",
  "number": "212 555-1234"
 },
{
  "type": "office",
  "number": "646 555-4567"
},
{
  "type": "mobile",
  "number": "123 456-7890"
}
],
"children": [],
"spouse": null

}

var obj = JObject.Parse(json);

var result = obj.Descendants()
.OfType<JProperty>()
.Select(p => new KeyValuePair<string, object>(p.Path,
    p.Value.Type == JTokenType.Array || p.Value.Type == JTokenType.Object
        ? null : p.Value));

foreach (var kvp in result)
  Console.WriteLine(kvp);

这段代码的输出如下:

[firstName, John]
[lastName, Smith]
[isAlive, True]
[age, 25]
[address, ]
[address.streetAddress, 21 2nd Street]
[address.city, New York]
[address.state, NY]
[address.postalCode, 10021-3100]
[phoneNumbers, ]
[phoneNumbers[0].type, home]
[phoneNumbers[0].number, 212 555-1234]
[phoneNumbers[1].type, office]
[phoneNumbers[1].number, 646 555-4567]
[phoneNumbers[2].type, mobile]
[phoneNumbers[2].number, 123 456-7890]
[children, ]
[spouse, ]

我想将它转换回原来的 JSON 结构。


下面ExtensionMethods可以帮助您在任何级别更新 json 中的任何键值。

public static class JsonExtensions
{
    public static void SetByPath(this JToken obj, string path, JToken value)
    {
        JToken token = obj.SelectToken(path);
        token.Replace(value);
    }

    public static List<JToken> FindTokens(this JToken containerToken, string name)
    {
        List<JToken> matches = new List<JToken>();
        FindTokens(containerToken, name, matches);
        return matches;
    }

    private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
    {
        if (containerToken.Type == JTokenType.Object)
        {
            foreach (JProperty child in containerToken.Children<JProperty>())
            {
                if (child.Name == name)
                {
                    matches.Add(child.Value);
                }
                FindTokens(child.Value, name, matches);
            }
        }
        else if (containerToken.Type == JTokenType.Array)
        {
            foreach (JToken child in containerToken.Children())
            {
                FindTokens(child, name, matches);
            }
        }
    }
}

在这里,我编写了一个自定义函数来查找键并替换它的值,

public static JToken FindAndReplace(JToken jToken, string key, JToken value, int? occurence)
{
    var searchedTokens = jToken.FindTokens(key);
    int count = searchedTokens.Count;

    if (count == 0)
        return $"The key you have to serach is not present in json, Key: {key}";

    foreach (JToken token in searchedTokens)
    {
        if (!occurence.HasValue)
            jToken.SetByPath(token.Path, value);
        else
        if (occurence.Value == searchedTokens.IndexOf(token))
            jToken.SetByPath(token.Path, value);
    }

    return jToken;
}

重要的:第四个参数是什么occurence意思是这里?

  • 如果你把null在此参数中,对于任何级别的 json 中指定键的所有出现,该值都将更新。
  • 如果你放置任何索引0, 1那么该值将在任意级别更新为 json 中指定键的指定索引。

你可以像这样使用它

string json = File.ReadAllText(@"Path to your json file");

JToken jToken = JToken.Parse(json);

jToken = FindAndReplace(jToken, "firstName", "Matthew", null);
jToken = FindAndReplace(jToken, "lastName", "Gilbert", null);
jToken = FindAndReplace(jToken, "streetAddress", "Falcon Ave, 91 Street, New Jersey", null);
jToken = FindAndReplace(jToken, "postalCode", "R12H34", null);

jToken = FindAndReplace(jToken, "type", "work", 0);
jToken = FindAndReplace(jToken, "number", "787-878-7878", 0);

jToken = FindAndReplace(jToken, "type", "factory", 1);
jToken = FindAndReplace(jToken, "number", "989-898-9898", 1);

string outputJson = jToken.ToString();

Output:

参考:布赖恩·罗杰斯 https://stackoverflow.com/a/19646950/5514820, senshin https://stackoverflow.com/a/33829388/5514820

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度查找或搜索 JSON 中任何级别的键并替换其在 C# 中的值 的相关文章

随机推荐