2011-09-24 37 views
15

Tôi đang cố gắng sử dụng JsonPath cho .NET (http://code.google.com/p/jsonpath/downloads/list) và tôi đang gặp khó khăn khi tìm một ví dụ về cách phân tích chuỗi Json và chuỗi JsonPath và nhận kết quả.Làm thế nào để sử dụng ví dụ C# bằng cách sử dụng JsonPath?

Có ai đã sử dụng quyền này không?

+4

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) –

+0

Tính năng này có một tính năng tương tự như JsonPath không? –

+3

Đ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 –

Trả lời

21

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ị JValueJObject.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:

+2

Thay vì viết nhiều mã và sử dụng hai thư viện, sẽ không dễ dàng hơn khi sử dụng Json.Net như thế này: JObject json = JObject.Parse (@input); var values ​​= json.SelectToken ("store.book") Giá trị ("tác giả"); –

+0

Câu trả lời này trả lời câu hỏi. Tất nhiên có nhiều cách tiếp cận khác tùy thuộc vào vấn đề đang được giải quyết. –

+0

Cảm ơn! Chính xác những gì tôi cần. SelectToken của Json.Net không có chức năng tôi cần. –

2

Đối với những người không thích LINQ (.NET 2.0):

namespace JsonPath 
{ 


    public sealed class JsonNetValueSystem : IJsonPathValueSystem 
    { 


     public bool HasMember(object value, string member) 
     { 
      if (value is Newtonsoft.Json.Linq.JObject) 
      { 
       // return (value as JObject).Properties().Any(property => property.Name == member); 

       foreach (Newtonsoft.Json.Linq.JProperty property in (value as Newtonsoft.Json.Linq.JObject).Properties()) 
       { 
        if (property.Name == member) 
         return true; 
       } 

       return false; 
      } 

      if (value is Newtonsoft.Json.Linq.JArray) 
      { 
       int index = ParseInt(member, -1); 
       return index >= 0 && index < (value as Newtonsoft.Json.Linq.JArray).Count; 
      } 
      return false; 
     } 


     public object GetMemberValue(object value, string member) 
     { 
      if (value is Newtonsoft.Json.Linq.JObject) 
      { 
       var memberValue = (value as Newtonsoft.Json.Linq.JObject)[member]; 
       return memberValue; 
      } 
      if (value is Newtonsoft.Json.Linq.JArray) 
      { 
       int index = ParseInt(member, -1); 
       return (value as Newtonsoft.Json.Linq.JArray)[index]; 
      } 
      return null; 
     } 


     public System.Collections.IEnumerable GetMembers(object value) 
     { 
      System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>(); 

      var jobject = value as Newtonsoft.Json.Linq.JObject; 
      /// return jobject.Properties().Select(property => property.Name); 

      foreach (Newtonsoft.Json.Linq.JProperty property in jobject.Properties()) 
      { 
       ls.Add(property.Name); 
      } 

      return ls; 
     } 


     public bool IsObject(object value) 
     { 
      return value is Newtonsoft.Json.Linq.JObject; 
     } 


     public bool IsArray(object value) 
     { 
      return value is Newtonsoft.Json.Linq.JArray; 
     } 


     public bool IsPrimitive(object value) 
     { 
      if (value == null) 
       throw new System.ArgumentNullException("value"); 

      return value is Newtonsoft.Json.Linq.JObject || value is Newtonsoft.Json.Linq.JArray ? false : true; 
     } 


     private int ParseInt(string s, int defaultValue) 
     { 
      int result; 
      return int.TryParse(s, out result) ? result : defaultValue; 
     } 


    } 


} 

Cách sử dụng:

object obj = Newtonsoft.Json.JsonConvert.DeserializeObject(input); 

JsonPath.JsonPathContext context = new JsonPath.JsonPathContext { ValueSystem = new JsonPath.JsonNetValueSystem() }; 

foreach (JsonPath.JsonPathNode node in context.SelectNodes(obj, "$.store.book[*].author")) 
{ 
    Console.WriteLine(node.Value); 
} 
Các vấn đề liên quan