如何将JToken添加到JObject?


84

我正在尝试使用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."

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

Answers:


139

我认为您对JSON.Net中的内容感到困惑。

  • AJToken是任何类型的JSON值的通用表示形式。它可以是字符串,对象,数组,属性等。
  • AJPropertyJToken与名称配对的单个值。只能将其添加到中JObject,其值不能是另一个JProperty
  • AJObject是的集合JProperties。它不能JToken直接持有任何其他种类。

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

您真正想做的是JPropertyJObject其中包含其他水果的香蕉上添加一个称为“香蕉”的香蕉JProperties。这是修改后的代码:

JObject foodJsonObj = JObject.Parse(jsonText);
JObject fruits = foodJsonObj["food"]["fruit"] as JObject;
fruits.Add("banana", JObject.Parse(@"{""colour"":""yellow"",""size"":""medium""}"));

7
注意:JObject.Parse在最后一行使用'JToken.Parse'(或'JToken.FromObject')代替。因为这也适用于简单的对象,例如字符串。
ctrl-alt-delor 2014年

如果我想覆盖Jproperty怎么办。
丹尼尔(Daniel)

@Daniel-如果通过“覆盖”来表示完全用JProperty另一种替换,则可以使用该Replace方法。如果您只想更改的值,则JProperty可以Value在其上设置属性;它是可写的。请参阅LINQ-to-JSON API参考
Brian Rogers

35

TL; DR:应该将JProperty添加到JObject。简单。索引查询返回一个JValue,因此找出如何获取JProperty :)


可接受的答案似乎并未回答该问题。如果要在特定的JProperty之后专门添加JProperty,该怎么办?首先,让我们从真正让我精打细算的术语开始。

  • JToken =所有其他类型的母亲。它可以是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,然后在此usingAddAfterSelf方法之后添加它。到此为止。

有关更多信息: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);
    }
  }
}

4
您的术语错误。 JToken(不JValue)是基类从其中JArrayJObjectJPropertyJValue最终继承。 JValue是表示字符串,数字,布尔值,日期或null值的JSON原语;它不能代表数组或对象。请参阅《LINQ-to-JSON API参考》
Brian Rogers

1
@BrianRogers谢谢,我修复了术语。
加桑2015年

1
这是对Newtonsoft对象模型的很好解释,现在我可以更好地了解newtonsoft.com/json/help/html/N_Newtonsoft_Json_Linq.htm。到目前为止,由于缺少文档中的详细说明,我的使用工作受到了阻碍。它似乎只是从代码注释中自动生成的参考。
汤姆·威尔逊

2
但是,代码示例mod不太正确:`var foodJsonObj = JObject.Parse(jsonText); var bananaJson = JObject.Parse(@“ {”“ colour”“:”“黄色”“,”“ size”“:”“中等”“}”)); var fruitJObject = foodJsonObj [“ food”] [“ fruit”]作为JObject; fruitJObject.Property(“ orange”)。AddAfterSelf(new JProperty(“ banana”,bananaJson)); `
汤姆·威尔逊,

我一生无法将代码标记应用于我以前的评论-AARRRGHH!我使用了回勾号并缩进了4个空格-我该怎么做?
汤姆·威尔逊

5

只需添加.First您的代码即可bananaToken:基本上是通过使其变为a而不是。
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First);
.First{JPropertyJToken

@Brian Rogers,谢谢,我忘记了.Parent。已编辑

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.