2017-09-14 7 views
0

다음 JSON 내부SelectTokens를 사용하여 JSON을 쿼리 하시겠습니까? C#에서 Newtonsoft.Json.Linq와 나는 다음과 같은 JSON에서 "에 statusCode"값을 변경하려면 C#으로 Netwonsoft.JSON.Linq을 활용하기 위해 노력하고있어

{ 
    "disbursements":[ 
     { 
     "id":"1f337641", 
     "contactId":"f5eb2", 
     "statusCode":166000005, 
     "amount":8, 
     "category":166000001 
     }, 
     { 
     "id":"027a4762", 
     "contactId":"f5eb2038", 
     "statusCode":166000000, 
     "amount":4000, 
     "category":166000000 
     } 
    ] 
} 

그래서 데이터는 JSON 배열 인 "지출"입니다. 배열의 각 항목의 "statusCode"를 166000005으로 변경해야합니다. 나는

JObject jsonText = JObject.Parse(bodyText); 
var statusCode = (int)jsonText.SelectToken("disbursements[0].statusCode"); 

사용하여 첫 번째 하나에 statusCode를 검색 할 수있어하지만 모든 값, 단지 첫째하지를 변경 루프 또는 LINQ와 솔루션이 필요합니다.

+1

1) 올바른 JSON 샘플을 제공하기 위해 질문을 편집 해 주실 수 있습니까? 현재 JSON은 https://jsonlint.com/에서 유효성 검사에 실패합니다. 어쩌면 그냥 외부 괄호'{'와'}'가 필요하겠습니까? 2) 당신은 다음과 같이 썼다. * 나는 '지불 [0] [ "statCode"]'*에 의해 statusCode를 검색 할 수있다. 시도한 내용과 작동하지 않는 이유를 보여줄 수 있습니까? 필요없는 대답을 추측하여 제공 할 필요가 없습니다. See [ask]. – dbc

+0

이것은 유효한 JSON이 아니지만 왜 객체를 순회 할 수 있습니까? Newtonsoft가 비 직렬화 되었습니까? –

+0

이것이 원하는 것입니까? [Json의 일부를 다른 것으로 바꾸기 (문자열 토큰 사용) C#, Json.Net] (https://stackoverflow.com/a/33056210/3744182). – dbc

답변

0

다음 코드 세트 또는 지급 배열의 모든 항목에 "statusCode": 166000005을 추가

var jsonText = JObject.Parse(bodyText); 
foreach (var disbursement in jsonText.SelectTokens("disbursements[*]")) 
{ 
    disbursement["statusCode"] = 166000005; 
} 

참고 :

  • 쿼리 문자열 "disbursements[*]"JSONPath 와일드 카드 연산자 [*]가 포함되어 있습니다. 이 연산자는 부모 요소 "disbursement" 아래의 모든 배열 요소를 찾습니다.

    Json.NET은 Querying JSON with JSONPath에 설명 된대로 JSONPath 구문을 지원합니다.

  • 이 사용되며 복수 가능한 일치를 반복하기 위해 SelectToken()이 반복됩니다.

  • JTokenitem setterdisbursement["statusCode"] = 166000005

    현재 경우 "statusCode" 속성을 교체하지 않을 경우에 추가합니다.

  • 166000005과 같은 단순한 원자 값은 JToken 계층으로 직접 설정할 수 있습니다. 복잡한 POCO 위해 당신은

    disbursement["statusCode"] = 
        JToken.FromObject(new { oldValue = disbursement["statusCode"], newValue = 166000005 }); 
    

샘플 .Net fiddle 작업 :, 계층 구조를 설정하기 전에 JToken에 직렬화 JToken.FromObject()를 호출 예컨대 필요합니다.

0

데이터를 나타내는 클래스를 만들 것입니다.

데이터 홀더 클래스를 만듭니다 : 여기 내 솔루션입니다

public class Disbursement 
{ 
    [JsonProperty("id")] 
    public string Id { get; set; } 

    [JsonProperty("contactId")] 
    public string ContactId { get; set; } 

    [JsonProperty("statusCode")] 
    public int StatusCode { get; set; } 

    [JsonProperty("amount")] 
    public int Amount { get; set; } 

    [JsonProperty("category")] 
    public int Category { get; set; } 
} 

컬렉션 :

public class Disbursements 
{ 
    [JsonProperty("disbursements")] 
    public List<Disbursement> Items { get; set; } = new List<Disbursement>(); 
} 

그리고로드/수정/데이터 저장 :

class Program 
{ 
    static void Main(string[] args) 
    { 
     var disbursements = 
      JsonConvert.DeserializeObject<Disbursements>(
       File.ReadAllText(
        "data.json", 
        Encoding.UTF8 
       ) 
      ); 

     foreach (var disbursement in disbursements.Items) 
     { 
      disbursement.StatusCode = 166000005; 
     } 

     string modifiedContent = JsonConvert.SerializeObject(disbursements); 

     File.WriteAllText(
      "modifiedData.json", 
      modifiedContent, 
      Encoding.UTF8 
     ); 
    } 
}