如何将JToken添加到JObject?

Jim*_*Jim 74 c# json.net

我正在尝试使用JSON.Net将JSON对象从某些文本添加到现有的JSON文件中.例如,如果我有如下的JSON数据:

  {
  "food": {
    "fruit": {
      "apple": {
        "colour": "red",
        "size": "small"
      },
      "orange": {
        "colour": "orange",
        "size": "large"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我一直试图这样做:

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);
Run Code Online (Sandbox Code Playgroud)

但是这给出了错误: "Newtonsoft.Json.Linq.JProperty cannot have multiple values."

我实际上尝试了几种不同的方法,但似乎无法到达任何地方.在我的例子中,我真正想要做的是将新项添加到"fruit".如果有更好的方法或更简单的库可供使用,请告诉我.

Bri*_*ers 121

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

  • A JToken是任何类型的JSON值的通用表示.它可以是字符串,对象,数组,属性等.
  • A JPropertyJToken与名称配对的单个值.它只能添加到a JObject,而它的值不能是另一个JProperty.
  • A JObject是一个集合JProperties.它不能JToken直接持有任何其他类型.

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

你真正想要做的是添加一个JProperty叫做"香蕉"的JObject包含其他水果的香蕉JProperties.这是修改后的代码:

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

  • 注意:在最后一行使用'JToken.Parse'(或'JToken.FromObject')而不是`JObject.Parse`.因为这也适用于简单的对象,如字符串. (7认同)

Gha*_*san 32

TL; DR:您应该将一个JProperty添加到JObject.简单.索引查询返回一个JValue,因此请弄清楚如何获取JProperty :)


接受的答案似乎没有回答这个问题.如果我想在特定的一个之后专门添加JProperty怎么办?首先,让我们从真正让我头脑清醒的术语开始吧.

  • JToken =所有其他类型的母亲.它可以是A JValue,JProperty,JArray或JObject.这是为解析机制提供模块化设计.
  • JValue =任何Json值类型(string,int,boolean).
  • JProperty =任何JValue或JContainer(见下文)与名称(标识符)配对.例如"name":"value".
  • JContainer =包含其他类型(JObject,JValue)的所有类型的母亲.
  • JObject =一个包含JProperties集合的JContainer类型
  • JArray =一个JContainer类型,它包含一个集合JValue或JContainer.

现在,当您使用index []查询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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的术语错了.`JToken`(不是`JValue`)是`JArray`,`JObject`,`JProperty`和`JValue`最终继承的基类.`JValue`是一个JSON原语,表示字符串,数字,布尔值,日期或空值; 它不能代表数组或对象.请参阅[LINQ-to-JSON API参考](http://www.newtonsoft.com/json/help/html/N_Newtonsoft_Json_Linq.htm). (3认同)
  • 但是,代码示例 mod 不太正确:` var foodJsonObj = JObject.Parse(jsonText); var bananJson = JObject.Parse(@"{ ""colour"": ""yellow"", ""size"": ""medium""}"); var FruitJObject = foodJsonObj["food"]["fruit"] as JObject; FruitJObject.Property("orange").AddAfterSelf(new JProperty("banana",bananaJson)); ` (3认同)

Rep*_*Dbg 5

只要添加.First到你bananaToken应该这样做:基本上移动过去使它成为一个而不是一个.
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First);
.First{JPropertyJToken

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