C# 如何将 JToken 添加到 JObject?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15413825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you add a JToken to an JObject?
提问by Jim
I'm trying to add a JSON object from some text to an existing JSON file using JSON.Net. For example if I have the JSON data as below:
我正在尝试使用 JSON.Net 将一些文本中的 JSON 对象添加到现有的 JSON 文件中。例如,如果我有如下的 JSON 数据:
{
"food": {
"fruit": {
"apple": {
"colour": "red",
"size": "small"
},
"orange": {
"colour": "orange",
"size": "large"
}
}
}
}
I've been trying to do this like this:
我一直在尝试这样做:
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);
But this gives the error: "Newtonsoft.Json.Linq.JProperty cannot have multiple values."
但这给出了错误: "Newtonsoft.Json.Linq.JProperty cannot have multiple values."
I've actually tried a few different ways but can't seem to get anywhere. In my example what I really want to do is add the new item to "fruit". Please let me know if there is a better way of doing this or a simpler library to use.
我实际上尝试了几种不同的方法,但似乎无处可去。在我的示例中,我真正想做的是将新项目添加到“fruit”。请让我知道是否有更好的方法或更简单的库来使用。
回答by Brian Rogers
I think you're getting confused about what can hold what in JSON.Net.
我认为您对 JSON.Net 中的内容感到困惑。
- A
JToken
is a generic representation of a JSON value of any kind. It could be a string, object, array, property, etc. - A
JProperty
is a singleJToken
value paired with a name. It can only be added to aJObject
, and its value cannot be anotherJProperty
. - A
JObject
is a collection ofJProperties
. It cannot hold any other kind ofJToken
directly.
- A
JToken
是任何类型的 JSON 值的通用表示。它可以是字符串、对象、数组、属性等。 - A
JProperty
是JToken
与名称配对的单个值。它只能添加到 aJObject
,其值不能是 anotherJProperty
。 - A
JObject
是 的集合JProperties
。它不能JToken
直接容纳任何其他类型。
In your code, you are attempting to add a JObject
(the one containing the "banana" data) to a JProperty
("orange") which already has a value (a JObject
containing {"colour":"orange","size":"large"}
). As you saw, this will result in an error.
在您的代码中,您试图将一个JObject
(包含“香蕉”数据的)添加到一个JProperty
(“橙色”)已经有一个值(JObject
包含{"colour":"orange","size":"large"}
)。如您所见,这将导致错误。
What you really want to do is add a JProperty
called "banana" to the JObject
which contains the other fruit JProperties
. Here is the revised code:
您真正想要做的是JProperty
在JObject
包含其他水果的 中添加一个名为“香蕉”的内容JProperties
。这是修改后的代码:
JObject foodJsonObj = JObject.Parse(jsonText);
JObject fruits = foodJsonObj["food"]["fruit"] as JObject;
fruits.Add("banana", JObject.Parse(@"{""colour"":""yellow"",""size"":""medium""}"));
回答by RepDbg
Just adding .First
to your bananaToken
should do it:foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken
.First
);
.First
basically moves past the {
to make it a JProperty
instead of a JToken
.
只是添加.First
到你bananaToken
应该做的:基本上移动过去使其成为一个而不是一个。 foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken
.First
);
.First
{
JProperty
JToken
@Brian Rogers, Thanks I forgot the .Parent
. Edited
@Brian Rogers,谢谢,我忘记了.Parent
. 已编辑
回答by Ghasan
TL;DR: You should add a JProperty to a JObject. Simple. The index query returns a JValue, so figure out how to get the JProperty instead :)
TL;DR:您应该将 JProperty 添加到 JObject。简单的。索引查询返回一个 JValue,所以弄清楚如何获取 JProperty :)
The accepted answer is not answering the question as it seems. What if I want to specifically add a JProperty after a specific one? First, lets start with terminologies which really had my head worked up.
接受的答案并没有像看起来那样回答问题。如果我想在特定的之后专门添加一个 JProperty 怎么办?首先,让我们从真正让我头脑清醒的术语开始。
- JToken = The mother of all other types. It can be A JValue, JProperty, JArray, or JObject. This is to provide a modular design to the parsing mechanism.
- JValue = any Json value type (string, int, boolean).
- JProperty = any JValue or JContainer (see below) paired with a name (identifier). For example
"name":"value"
. - JContainer = The mother of all types which contain other types (JObject, JValue).
- JObject = a JContainer type that holds a collection of JProperties
- JArray = a JContainer type that holds a collection JValue or JContainer.
- JToken = 所有其他类型之母。它可以是 JValue、JProperty、JArray 或 JObject。这是为解析机制提供模块化设计。
- JValue = 任何 Json 值类型(字符串、整数、布尔值)。
- JProperty = 与名称(标识符)配对的任何 JValue 或 JContainer(见下文)。例如
"name":"value"
。 - JContainer = 包含其他类型(JObject、JValue)的所有类型之母。
- JObject = 包含 JProperties 集合的 JContainer 类型
- JArray = 包含集合 JValue 或 JContainer 的 JContainer 类型。
Now, when you query Json item using the index [], you are getting the JToken without the identifier, which might be a JContainer or a JValue (requires casting), but you cannot add anything after it, because it is only a value. You can change it itself, query more deep values, but you cannot add anything after it for example.
现在,当您使用索引 [] 查询 Json 项时,您将获得没有标识符的 JToken,它可能是 JContainer 或 JValue(需要强制转换),但您不能在其后添加任何内容,因为它只是一个值。您可以自行更改它,查询更深的值,但例如不能在其后添加任何内容。
What you actually want to get is the property as whole, and then add another property after it as desired. For this, you use JOjbect.Property("name")
, and then create another JProperty of your desire and then add it after this using AddAfterSelf
method. You are done then.
您实际想要获得的是整个属性,然后根据需要在其后添加另一个属性。为此,您使用JOjbect.Property("name")
,然后创建您想要的另一个 JProperty,然后在此 usingAddAfterSelf
方法之后添加它。那么你就完成了。
For more info: http://www.newtonsoft.com/json/help/html/ModifyJson.htm
更多信息:http: //www.newtonsoft.com/json/help/html/ModifyJson.htm
This is the code I modified.
这是我修改的代码。
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);
}
}
}