如何将一个JToken添加到一个JObject?
我试图从一些文本添加JSON对象到现有的使用JSON.Net的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
是任何types的JSON值的通用表示。 它可能是一个string,对象,数组,属性等 -
JProperty
是与名称配对的单个JToken
值。 它只能被添加到一个JObject
,它的值不能是另一个JProperty
。 -
JObject
是JObject
的集合。 它不能直接持有任何其他types的JToken
。
在你的代码中,你试图添加一个JObject
(包含“banana”数据的JProperty
)到已经有一个值的JProperty
(“orange”)(一个JObject
包含{"colour":"orange","size":"large"}
)。 正如你所看到的,这将导致错误。
你真正想做的是添加一个JProperty
称为“香蕉” JObject
包含其他水果JProperties
。 这里是修改后的代码:
JObject foodJsonObj = JObject.Parse(jsonText); JObject fruits = foodJsonObj["food"]["fruit"] as JObject; fruits.Add("banana", JObject.Parse(@"{""colour"":""yellow"",""size"":""medium""}"));
TL; DR:您应该将JProperty添加到JObject。 简单。 索引查询返回一个JValue,所以找出如何获得JProperty 🙂
接受的答案是不回答这个问题。 如果我想专门添加一个特定的JProperty? 首先,让我们从真正头脑发展的术语开始。
- JToken =所有其他types的母亲。 它可以是JValue,JProperty,JArray或JObject。 这是为parsing机制提供模块化devise。
- JValue =任何Json值types(string,int,boolean)。
- JProperty =与名称(标识符)配对的任何JValue或JContainer(见下文) 。 例如
"name":"value"
。 - JContainer =包含其他types(JObject,JValue)的所有types的母亲。
- JObject =一个拥有JProperties集合的JContainertypes
- JArray =包含集合JValue或JContainer的JContainertypes。
现在,当您使用index []查询Json项目时,您将得到没有标识符的JToken(可能是JContainer或JValue(需要强制转换)),但不能在其后面添加任何内容,因为它只是一个值。 你可以自己改变它,查询更深的值,但是你不能在它之后添加任何东西。
你实际上想要得到的是整个属性,然后根据需要添加另一个属性。 为此,您使用JOjbect.Property("name")
,然后创build您的愿望的另一个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); } } }
只要join.First
你的bananaToken
应该做到这一点:
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken
.First
基本上移过{
使其成为JProperty
而不是JToken
。
@Brian Rogers,谢谢,我忘了.Parent
。 编辑