Sự cố bạn gặp phải là phiên bản C# của JsonPath không bao gồm trình phân tích cú pháp Json, do đó bạn phải sử dụng nó với khung Json khác xử lý tuần tự hóa và deserialization.
Cách JsonPath hoạt động là sử dụng giao diện được gọi là IJsonPathValueSystem
để duyệt qua các đối tượng Json được phân tích cú pháp. JsonPath đi kèm với một built-in BasicValueSystem
sử dụng giao diện IDictionary
để đại diện cho các đối tượng Json và giao diện IList
để biểu diễn các mảng Json.
Bạn có thể tạo các đối tượng Json riêng tương thích BasicValueSystem
bằng cách xây dựng chúng bằng cách sử dụng bộ khởi tạo bộ sưu tập C# nhưng điều này không được sử dụng nhiều khi Json của bạn đến dưới dạng chuỗi từ máy chủ từ xa. Vì vậy, nếu chỉ bạn có thể lấy một chuỗi Json và phân tích nó thành một cấu trúc lồng nhau của các đối tượng IDictionary
, các mảng IList
và các giá trị nguyên thủy, thì bạn có thể sử dụng JsonPath để lọc nó! Như may mắn sẽ có nó, chúng ta có thể sử dụng Json.NET có khả năng serialization và deserialization tốt để làm điều đó một phần của công việc.
Thật không may, Json.NET không deserialize chuỗi Json thành một định dạng tương thích với BasicValueSystem
. Vì vậy, nhiệm vụ đầu tiên để sử dụng JsonPath với Json.NET là viết một JsonNetValueSystem
thực hiện IJsonPathValueSystem
và hiểu các đối tượng JObject
, các mẫu JArray
và các giá trị JValue
mà JObject.Parse
tạo ra.
Vì vậy, hãy tải xuống cả JsonPath và Json.NET và đưa chúng vào dự án C#. Sau đó thêm lớp này đến dự án mà:
public sealed class JsonNetValueSystem : IJsonPathValueSystem
{
public bool HasMember(object value, string member)
{
if (value is JObject)
return (value as JObject).Properties().Any(property => property.Name == member);
if (value is JArray)
{
int index = ParseInt(member, -1);
return index >= 0 && index < (value as JArray).Count;
}
return false;
}
public object GetMemberValue(object value, string member)
{
if (value is JObject)
{
var memberValue = (value as JObject)[member];
return memberValue;
}
if (value is JArray)
{
int index = ParseInt(member, -1);
return (value as JArray)[index];
}
return null;
}
public IEnumerable GetMembers(object value)
{
var jobject = value as JObject;
return jobject.Properties().Select(property => property.Name);
}
public bool IsObject(object value)
{
return value is JObject;
}
public bool IsArray(object value)
{
return value is JArray;
}
public bool IsPrimitive(object value)
{
if (value == null)
throw new ArgumentNullException("value");
return value is JObject || value is JArray ? false : true;
}
private int ParseInt(string s, int defaultValue)
{
int result;
return int.TryParse(s, out result) ? result : defaultValue;
}
}
Bây giờ với tất cả ba những mảnh chúng ta có thể viết một chương trình mẫu JsonPath:
class Program
{
static void Main(string[] args)
{
var input = @"
{ ""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
}
}
}
";
var json = JObject.Parse(input);
var context = new JsonPathContext { ValueSystem = new JsonNetValueSystem() };
var values = context.SelectNodes(json, "$.store.book[*].author").Select(node => node.Value);
Console.WriteLine(JsonConvert.SerializeObject(values));
Console.ReadKey();
}
}
trong đó sản xuất sản lượng này:
["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
Ví dụ này dựa trên mẫu Javascript tại trang web JsonPath:
Có thể tôi đề nghị Json.NET như một JSON thay thế trình phân tích cú pháp (http://james.newtonking.com/pages/json-net.aspx) –
Tính năng này có một tính năng tương tự như JsonPath không? –
Điều gì đó tương tự như XPath? Nó có. Kiểm tra chức năng SelectToken của JSON.NET. Bạn có thể sử dụng một biểu thức chuỗi để nhận JSON. Ví dụ: http: // stackoverflow.com/questions/1698175/what-is-the-json-net-equivilant-of-xmls-xpath-selectnodes-selectsinglenode –