如何将 JToken 添加到 JObject 中
本文关键字:JObject 添加 JToken | 更新日期: 2023-09-27 18:03:50
我正在尝试使用 JSON.Net 将某些文本中的 JSON 对象添加到现有的 JSON 文件中。例如,如果我有如下 JSON 数据:
{
"food": {
"fruit": {
"apple": {
"colour": "red",
"size": "small"
},
"orange": {
"colour": "orange",
"size": "large"
}
}
}
}
我一直在尝试这样做:
var foodJsonObj = JObject.Parse(jsonText);
var bananaJson = JObject.Parse(@"{ ""banana"" : { ""colour"": ""yellow"", ""size"": ""medium""}}");
var bananaToken = bananaJson as JToken;
foodJsonObj["food"]["fruit"]["orange"].AddAfterSelf(bananaToken);
但这给出了错误:"Newtonsoft.Json.Linq.JProperty cannot have multiple values."
我实际上已经尝试了几种不同的方法,但似乎无济于事。在我的示例中,我真正想做的是将新项目添加到"水果"中。请让我知道是否有更好的方法或更简单的库可以使用。
我想你对什么可以容纳 JSON.Net 感到困惑。
JToken
是任何类型的 JSON 值的泛型表示形式。 它可以是字符串、对象、数组、属性等。JProperty
是与名称配对的单个JToken
值。 它只能添加到一个JObject
,并且它的值不能是另一个JProperty
。JObject
是JProperties
的集合。 它不能直接持有任何其他类型的JToken
。
在代码中,您尝试将JObject
(包含"香蕉"数据的(添加到已具有值(包含{"colour":"orange","size":"large"}
的JObject
(的JProperty
("橙色"(。 如您所见,这将导致错误。
您真正想做的是在包含其他水果JProperties
的JObject
中添加一个名为"香蕉"的JProperty
。 以下是修订后的代码:
JObject foodJsonObj = JObject.Parse(jsonText);
JObject fruits = foodJsonObj["food"]["fruit"] as JObject;
fruits.Add("banana", JObject.Parse(@"{""colour"":""yellow"",""size"":""medium""}"));
TL;DR:你应该在 JObject 中添加一个 JProperty。简单。索引查询返回一个 JValue,因此弄清楚如何获取 JProperty 而不是:)
接受的答案并没有回答看起来的问题。如果我想在特定之后专门添加 JProperty 怎么办?首先,让我们从真正让我头疼的术语开始。
- JToken = 所有其他类型的母亲。它可以是 A JValue、JProperty、JArray 或 JObject。这是为了向解析机制提供模块化设计。
- JValue = 任何 Json 值类型(字符串、整数、布尔值(。
- JProperty = 任何与名称(标识符(配对的 JValue 或 JContainer(见下文(。例如
"name":"value"
. - JContainer = 包含其他类型(JObject,JValue(的所有类型的母体。
- JObject = 一个 JContainer 类型,它包含 JProperties 的集合
- JArray = 保存集合 JValue 或 JContainer 的 JContainer 类型。
现在,当您使用索引 [] 查询 Json 项时,您将获得没有标识符的 JToken,这可能是 JContainer 或 JValue(需要强制转换(,但您不能在其后添加任何内容,因为它只是一个值。例如,您可以更改它本身,查询更深的值,但不能在它之后添加任何内容。
您实际想要获得的是整个属性,然后根据需要在其后添加另一个属性。为此,您可以使用 JOjbect.Property("name")
,然后创建您想要的另一个 JProperty,然后在此之后使用AddAfterSelf
方法添加它。那你就完了。
更多信息: http://www.newtonsoft.com/json/help/html/ModifyJson.htm
这是我修改的代码。
public class Program
{
public static void Main()
{
try
{
string jsonText = @"
{
""food"": {
""fruit"": {
""apple"": {
""colour"": ""red"",
""size"": ""small""
},
""orange"": {
""colour"": ""orange"",
""size"": ""large""
}
}
}
}";
var foodJsonObj = JObject.Parse(jsonText);
var bananaJson = JObject.Parse(@"{ ""banana"" : { ""colour"": ""yellow"", ""size"": ""medium""}}");
var fruitJObject = foodJsonObj["food"]["fruit"] as JObject;
fruitJObject.Property("orange").AddAfterSelf(new JProperty("banana", fruitJObject));
Console.WriteLine(foodJsonObj.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
}
}
}
只需将.First
添加到您的bananaToken
中即可:
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken
.First
);
.First
基本上会越过{
,使其成为JProperty
而不是JToken
。
@Brian罗杰斯,谢谢我忘记了.Parent
.编辑