如何将 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."

我实际上已经尝试了几种不同的方法,但似乎无济于事。在我的示例中,我真正想做的是将新项目添加到"水果"中。请让我知道是否有更好的方法或更简单的库可以使用。

如何将 JToken 添加到 JObject 中

我想你对什么可以容纳 JSON.Net 感到困惑。

  • JToken是任何类型的 JSON 值的泛型表示形式。 它可以是字符串、对象、数组、属性等。
  • JProperty是与名称配对的单个JToken值。 它只能添加到一个JObject,并且它的值不能是另一个JProperty
  • JObjectJProperties的集合。 它不能直接持有任何其他类型的JToken

在代码中,您尝试将JObject(包含"香蕉"数据的(添加到已具有值(包含{"colour":"orange","size":"large"}JObject(的JProperty("橙色"(。 如您所见,这将导致错误。

您真正想做的是在包含其他水果JPropertiesJObject中添加一个名为"香蕉"的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.编辑