종종 가변적인 구조의 JSON 데이터를 C#에서 다뤄야 할 경우나 혹은 JSON내의 특정 데이터만 추출 혹은 수정을 원할경우 일일이 맵핑할 class들을 만들어서 JSON 데이터를 다루기보다 JObject로 parsing 후 아래와 같이 SelectToken/SelectTokes 함수들을 사용해서 원하는 token을 찾아서 값을 가져오거나 조작하는 것이 훨씬 효율적입니다.
원문: https://www.newtonsoft.com/json/help/html/SelectToken.htm
1. SelectToken
SelectToken은 JToken을 리턴하는 method이며 하위 토큰에 대한 문자열 경로를 사용합니다. SelectToken은 하위 토큰을 반환하거나 경로 위치에서 토큰을 찾을 수 없는 경우 null 참조를 반환합니다.
경로는 마침표로 구분된 속성 이름과 배열 인덱스로 구성됩니다. 예) Manufacturers[0].Name.
JObject o = JObject.Parse(@"{
'Stores': [
'Lambton Quay',
'Willis Street'
],
'Manufacturers': [
{
'Name': 'Acme Co',
'Products': [
{
'Name': 'Anvil',
'Price': 50
}
]
},
{
'Name': 'Contoso',
'Products': [
{
'Name': 'Elbow Grease',
'Price': 99.95
},
{
'Name': 'Headlight Fluid',
'Price': 4
}
]
}
]
}");
string name = (string)o.SelectToken("Manufacturers[0].Name");
// Acme Co
decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
// 50
string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
// Elbow Grease
2. SelectToken with JSONPath
JSONPath(https://goessner.net/articles/JsonPath/) 표현식을 이용해서 token을 가져올 수 있습니다.
JObject o = JObject.Parse(@"{
'Stores': [
'Lambton Quay',
'Willis Street'
],
'Manufacturers': [
{
'Name': 'Acme Co',
'Products': [
{
'Name': 'Anvil',
'Price': 50
}
]
},
{
'Name': 'Contoso',
'Products': [
{
'Name': 'Elbow Grease',
'Price': 99.95
},
{
'Name': 'Headlight Fluid',
'Price': 4
}
]
}
]
}");
// manufacturer with the name 'Acme Co'
JToken acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");
Console.WriteLine(acme);
// { "Name": "Acme Co", Products: [{ "Name": "Anvil", "Price": 50 }] }
// name of all products priced 50 and above
IEnumerable<JToken> pricyProducts = o.SelectTokens("$..Products[?(@.Price >= 50)].Name");
foreach (JToken item in pricyProducts)
{
Console.WriteLine(item);
}
// Anvil
// Elbow Grease
3. SelectToken with LINQ
SelectToken 함수와 표준 LINQ 함수를 함께 사용해서 Token를 가져올 수 있습니다.
IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
// Lambton Quay
// Willis Street
IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
// null
// Headlight Fluid
decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
// 149.95
'Development > C#' 카테고리의 다른 글
[C#] HMACSHA256 클래스를 이용해서 사용자 비밀번호를 암호화하기 (0) | 2023.02.15 |
---|---|
[C#] Project publish할 때 "Could not find a part of the path..." 오류가 발생할 경우 (0) | 2023.02.12 |
[NLog] log message가 발생할 때 마다 호출되는 callback 함수 만들기 (0) | 2023.02.08 |
[C#] 두 변수의 값 바꾸기(Swap) (0) | 2023.02.07 |
[C#] JSON Serialization 할 때 enum 타입을 문자열 형태로 변환시키기 (0) | 2023.01.19 |