JObject에 JToken을 어떻게 추가합니까?


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."

실제로 몇 가지 다른 방법을 시도했지만 아무데도 갈 수없는 것 같습니다. 제 예에서 제가 정말로하고 싶은 것은 "과일"에 새 항목을 추가하는 것입니다. 이 작업을 수행하는 더 좋은 방법이나 사용하기 더 간단한 라이브러리가 있는지 알려주십시오.

답변:


139

JSON.Net에서 무엇이 담을 수 있는지에 대해 혼란스러워하고 있다고 생각합니다.

  • A JToken는 모든 종류의 JSON 값에 대한 일반적인 표현입니다. 문자열, 객체, 배열, 속성 등이 될 수 있습니다.
  • A JPropertyJToken이름과 쌍을 이루는 단일 값입니다. 에만 추가 할 JObject수 있으며 다른 값이 될 수 없습니다 JProperty.
  • A JObjectJProperties. 다른 종류의 JToken직접 담을 수 없습니다 .

코드에서 이미 값 (을 포함 ) 이있는 ( "주황색")에 ( " JObject바나나"데이터를 포함하는 것) 을 추가하려고합니다 . 보시다시피 오류가 발생합니다.JPropertyJObject{"colour":"orange","size":"large"}

정말로하고 싶은 것은 다른 과일을 포함하는 JProperty"바나나"를 추가하는 것 입니다. 수정 된 코드는 다음과 같습니다.JObjectJProperties

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

Jproperty를 덮어 쓰려면 어떻게해야합니까?
Daniel

@Daniel- "덮어 쓰기"로를 완전히 JProperty다른 것으로 바꾸려는 경우이 Replace방법을 사용할 수 있습니다 . 의 값만 변경 JProperty하려면 Value속성을 설정할 수 있습니다 . 쓰기 가능합니다. 참고 항목 LINQ - 투 - JSON API 참조 .
Brian Rogers

35

요약 : JObject에 JProperty를 추가해야합니다. 단순한. 인덱스 쿼리는 JValue를 반환하므로 대신 JProperty를 얻는 방법을 찾으십시오. :)


받아 들여지는 대답은 보이는 것처럼 질문에 대답하지 않습니다. 특정 속성 뒤에 JProperty를 구체적으로 추가하려면 어떻게해야합니까? 먼저, 내 머리가 제대로 작동하는 용어부터 시작하겠습니다.

  • JToken = 다른 모든 유형의 어머니. A JValue, JProperty, JArray 또는 JObject 일 수 있습니다. 이는 구문 분석 메커니즘에 모듈 식 설계를 제공하기위한 것입니다.
  • JValue = 모든 Json 값 유형 (문자열, 정수, 부울).
  • JProperty = 이름 (식별자) 과 쌍을 이루는 JValue 또는 JContainer (아래 참조 ) . 예를 들면 "name":"value".
  • JContainer = 다른 유형 (JObject, JValue)을 포함하는 모든 유형의 어머니.
  • JObject = JProperties 컬렉션을 보유하는 JContainer 유형
  • JArray = 콜렉션 JValue 또는 JContainer를 보유하는 JContainer 유형.

이제 인덱스 []를 사용하여 Json 항목을 쿼리 할 때 JContainer 또는 JValue (캐스팅 필요) 일 수있는 식별자없이 JToken을 얻지 만 값일 뿐이므로 그 뒤에 아무것도 추가 할 수 없습니다. 자체적으로 변경하고 더 깊은 값을 쿼리 할 수 ​​있지만 예를 들어 그 뒤에는 아무것도 추가 할 수 없습니다.

실제로 얻고 자하는 것은 전체 속성이고 원하는대로 그 뒤에 다른 속성을 추가합니다. 이를 위해를 사용 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);
    }
  }
}

4
용어가 잘못되었습니다. JToken(안 JValue) 기본 클래스 어떤로부터 JArray, JObject, JProperty그리고 JValue궁극적으로 상속합니다. JValue문자열, 숫자, 부울, 날짜 또는 널값을 나타내는 JSON 기본 요소입니다. 배열이나 객체를 나타낼 수 없습니다. 참고 항목 LINQ - 투 - JSON API 참조 .
Brian Rogers

1
@BrianRogers 감사합니다. 용어를 수정했습니다.
Ghasan

1
이것은 Newtonsoft 개체 모델에 대한 매우 좋은 설명이며 이제 newtonsoft.com/json/help/html/N_Newtonsoft_Json_Linq.htm을 훨씬 더 잘 이해할 수 있습니다. 지금까지 그것을 사용하려는 노력은 문서에 자세한 설명이 부족하여 방해를 받았습니다. 코드 주석에서 자동 생성 된 참조 인 것 같습니다.
톰 윌슨

2
그러나 코드 예제 mod는 옳지 않습니다.`var foodJsonObj = JObject.Parse (jsonText); var bananaJson = JObject.Parse (@ "{" "colour" ":" "yellow" "," "size" ":" "medium" "}"); var fruitJObject = foodJsonObj [ "food"] [ "fruit"] as JObject; fruitJObject.Property ( "orange"). AddAfterSelf (new JProperty ( "banana", bananaJson)); `
Tom Wilson

나는 평생 동안 내 이전 댓글에 코드 마크 업을 적용 할 수 없습니다-AARRGHH! 백틱을 사용하고 4 칸 들여 쓰기를했습니다. 어떻게해야합니까?
톰 윌슨

5

그냥 추가 .FirstbananaToken그것을 수행해야합니다 기본적으로 과거 이동 그것을 만들기 위해 대신을 .
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First);
.First{JPropertyJToken

@Brian Rogers, 감사합니다 .Parent. 수정 됨

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.