Я использую JsonPath для C# для запроса некоторых данных JSON. JsonPath не имеет собственного синтаксического анализатора, поэтому согласно Совет Рика Сладки, я использую Json.NET чтобы разобрать мою строку Json на набор вложенных объектов IDictionary
, массивов IList
и примитивов. Затем я использую JsonPath для его фильтрации (после добавления класса, предложенного в Ответ Рика Сладки).
Для справки, вот часть моего кода, которая на самом деле обрабатывает все это:
// string exampleJsonString defined below
string query = "$.store.book[*].title" // we should get a list of all titles
// step 1: use Json.NET to parse the json string into a JObject
JObject parsedJson = JObject.Parse(exampleJsonString);
// step 2: use JsonPath with a custom ValueSystem (JsonNetValueSystem)
JsonPathContext context = new JsonPathContext
{ ValueSystem = new JsonNetValueSystem() };
// step 3: get results using JsonPath
List<object> toRet = context.SelectNodes(parsedJson,
query).Select(node => node.Value).ToList();
Причина, по которой я использовал JsonPath в первую очередь, заключалась в его функциональности фильтра. Вы можете выполнять не только обычные запросы, такие как "$.store.book[*].title"
(чтобы получить массив всех заголовков в книжном магазине), но и такие запросы, как "$.store.book[?(@.category == 'fiction')].title"
(чтобы получить массив всех заголовков в книжном магазине, категория которых соответствует «художественной литературе»). Мне нужно иметь возможность передавать целые запросы в виде строки, поэтому возможность фильтрации во время запросов чрезвычайно полезна.
К сожалению, у меня возникли проблемы с работой этого фильтра. Я ожидаю, что мне придется внести коррективы либо в класс JsonNetValueSystem (первоначально определенный в вышеупомянутый ответ на переполнение стека) или пространство имен JsonPath (вы можете получить JsonPath.cs из кодовая страница Google JsonPath). Если есть какой-то внешний инструмент или альтернативный механизм синтаксического анализа для Json.NET, который позволил бы мне сохранить фильтрацию JsonPath без необходимости писать слишком много дополнительного кода, это было бы идеально, но я почти уверен, что мне придется изменить либо JsonNetValueSystem или сам JsonPath. (Оба из них довольно легко изменить, поскольку это всего лишь файлы .cs, но я не могу копаться в Json.NET без дополнительной работы.)
На самом деле я не могу понять, где исходный код JsonPath обрабатывает фильтрацию, и не могу понять, почему класс JsonNetValueSystem лишает его этой функциональности. Будем очень признательны за любые советы о том, как добавить возможность фильтрации в строку запроса. Даже если это просто «не связывайтесь с JsonPath, просто измените JsonNetValueSystem» или наоборот.
string exampleJsonString = "{
"store": {
"book": [ {
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
}, {
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}, {
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}, {
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
} ],
"bicycle": [ {
"color": "red",
"price": 19.95,
"style": [ "city", "hybrid" ]
}, {
"color": "blue",
"price": 59.91,
"style": [ "downhill", "freeride" ]
} ]
}
}"