Development/C#
[Json.Net] SelectToken/SelectTokens 사용법
아빠는개발자
2023. 1. 25. 11:16
종종 가변적인 구조의 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