如何根据路径向 JSON 添加新的 JProperty? [英] How to add a new JProperty to a JSON based on path?

查看:39
本文介绍了如何根据路径向 JSON 添加新的 JProperty?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个很大的 JSON 文件(大约一千行).任务是更新现有的 JProperties,或在结构中的特定位置添加新的 JProperties.新文本的位置基于 JToken.Path 属性.例如,这是 JSON 的开头:

There is a large JSON file (about a thousand lines). The task is to update existing JProperties, or add new JProperties in a specific location in the structure. The location of the new texts are based on the JToken.Path property. For example, this is the start of the JSON:

"JonSnow": {
    "Direwolf": {
        "Name": "Ghost",
        "Color": "White",
    }
}
"DanaerysTargaryen": {
    "Dragons": {
        "Dragon1": {
            "Name": "Drogon",
        }
    }
    "Hair": {
        "Color": "White"
    }
}

现在必须使用给定的 JToken 路径列表和相应的值来更新 JSON.

Now the JSON must be updated using a given list of JToken paths and the corresponding values.

第一种可能是路径对应的JProperty可能已经存在,此时需要更新值.我已经使用 JToken.Replace() 成功实现了这一点.

The first possibility is, the JProperty corresponding to the path might already exist, in which case the value needs to be updated. I am already successfully implementing this with JToken.Replace().

第二种可能是,JProperty 还不存在,需要添加.例如,我需要添加 "DanaerysTargaryen.Dragons.Dragon1.Color" 值为 "Black".

The second possibility is, the JProperty does not exist yet and needs to be added. For example, I need to add "DanaerysTargaryen.Dragons.Dragon1.Color" with the value "Black".

我知道我可以使用 JSON.Net Add() 方法,但要使用此方法,JSON 中只能缺少路径的最终子标记.例如,我可以使用

I know I can use the JSON.Net Add() method, but to use this only the final child token of the path can be missing from the JSON. For example, I can use

JObject ObjToUpdate= JObject.Parse(jsonText);
JObject Dragon = ObjToUpdate["DanaerysTargaryen"]["Dragons"]["Dragon1"] as JObject;
Dragon.Add("Color", "Black"));

但是如果我需要添加 "JonSnow.Weapon.Type" 和值 "Longsword" 怎么办?因为 "Weapon" 还没有作为 JProperty 存在,需要与 "Type" : "Longsword" 一起添加.对于每条路径,JSON 中已经存在多少路径是未知.这如何参数化?

But what about if I need to add "JonSnow.Weapon.Type" with the value "Longsword"? Because "Weapon" does not exist yet as a JProperty, and it needs to be added along with "Type" : "Longsword". With each path, it is unknown how much of the path already exists in the JSON. How can this be parameterised?

// from outside source: Dictionary<string, string> PathBasedDict 
// key: Jtoken.Path (example: "JonSnow.Weapon.Type")
// value: new text to be added (example: "Longsword")

foreach(KeyValuePair entry in PathBasedDict)
{
    string path = entry.Key;
    string newText = entry.Value;

    if (ObjToUpdate.SelectToken(path) != null)  
        { ObjToUpdate.SelectToken(path).Replace(newText); }

    else AddToJson(path, newText);
}

AddToJson() 应该是什么样子?遍历整个路径并检查每个可能的 JProperty 以查看它是否存在,然后将其余部分添加到下面,似乎非常麻烦.有一个更好的方法吗?我不知道的任何 Json.NET 技巧?我什至不确定如何将迭代参数化.

What should AddToJson() look like? Iterating through the entire path and checking each possible JProperty to see if it exists, and then adding the rest underneath, seems very cumbersome. Is there a better way to do this? Any Json.NET tricks I am unaware of? I am not even sure how the iteration could be parameterised.

推荐答案

有几种方法可以解决这个问题.这是其中的两个.

There are a few ways of going about this. Here are two of them.

  1. 要使用现有代码,请按 '.' 分割路径,然后对其进行迭代.如果路径不存在,请使用 Add 创建它.否则,如果我们在路径的最后一部分,只需添加值.

  1. To go along with your existing code, split the path by '.', then iterate over them. If the path is not there, create it with Add. Otherwise, if we're on the last part of the path, just add the value.

var json = JObject.Parse(@"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Name"": ""Drogon""}},""Hair"": {""Color"": ""White""}}}");
var toAdd = "DanaerysTargaryen.Dragons.Dragon1.Color";
var valueToAdd = "Black";
var pathParts = toAdd.Split('.');
JToken node = json;
for (int i = 0; i < pathParts.Length; i++)
{
    var pathPart = pathParts[i];
    var partNode = node.SelectToken(pathPart);
    if (partNode == null && i < pathParts.Length - 1)
    {
        ((JObject)node).Add(pathPart, new JObject());
        partNode = node.SelectToken(pathPart);
    }
    else if (partNode == null && i == pathParts.Length - 1)
    {
        ((JObject)node).Add(pathPart, valueToAdd);
        partNode = node.SelectToken(pathPart);
    }
    node = partNode;
}

Console.WriteLine(json.ToString());

(dotnetfiddle.net 上的示例)

  1. 否则,您可以创建一个单独的 JObject 来表示您要添加的节点,然后将它们合并.

  1. Otherwise, you could create a separate JObject that represents the node(s) you want to add, then merge them.

 var json = JObject.Parse(@"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Name"": ""Drogon""}},""Hair"": {""Color"": ""White""}}}");
 var toMerge = @"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Color"":""Black""}}}}";
 var jsonToMerge = JObject.Parse(toMerge);
 json.Merge(jsonToMerge);
 Console.WriteLine(json.ToString());

(dotnetfiddle.net 上的示例)

这篇关于如何根据路径向 JSON 添加新的 JProperty?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆