2011-09-24 23 views
15

我正在嘗試使用JsonPath for .NET(http://code.google.com/p/jsonpath/downloads/list),並且無法找到如何解析Json字符串和JsonPath字符串並獲取結果的示例。如何使用C#示例使用JsonPath?

有沒有人用過這個?

+4

也許我建議Json.NET作爲替代JSON解析器(http://james.newtonking.com/pages/json-net.aspx) –

+0

它是否具有類似於JsonPath的功能? –

+3

與XPath類似的東西?它的確如此。查看JSON.NET的SelectToken功能。您可以使用字符串表達式來獲取JSON。例如:http:// stackoverflow。com/questions/1698175/what-is-the-json-net-equivilant-of-xmls-xpath-selectnodes-selectsinglenode –

回答

21

您遇到的問題是JsonPath的C#版本不包含Json解析器,因此您必須將其與另一個處理序列化和反序列化的Json框架一起使用。

JsonPath的工作方式是使用名爲IJsonPathValueSystem的接口來遍歷解析的Json對象。 JsonPath帶有一個內置的BasicValueSystem,它使用IDictionary接口來表示Json對象,並使用IList接口來表示Json數組。例如,您可以使用C#集合初始化工具創建您自己的BasicValueSystem兼容Json對象,但是當您的Json以字符串形式從遠程服務器進入時,這並不是很有用。

所以,如果只有你可能需要一個JSON字符串,並將其解析爲IDictionary對象,IList數組和原始值的嵌套結構,你可以再使用JsonPath過濾吧!幸運的是,我們可以使用具有良好序列化和反序列化功能的Json.NET來完成這部分工作。

不幸的是,Json.NET不會將Json字符串反序列化爲與BasicValueSystem兼容的格式。因此,將JsonPath與Json.NET一起使用的第一項任務是編寫一個JsonNetValueSystem,它們實現IJsonPathValueSystem並且理解JObject.Parse產生的JObject對象,JArray數組和JValue值。

所以下載JsonPath和Json.NET並把它們放到C#項目中。那麼這個類添加到項目:

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; 
    } 
} 
這些作品,我們可以寫一個樣本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(); 
    } 
} 

產生這樣的輸出:

["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] 

本示例基於JsonPath站點上的Javascript示例:

+2

JObject json = JObject.Parse(@input);這樣就不會像使用Json.Net那樣更容易使用Json.Net。 var values = json.SelectToken(「store.book」)。Values(「author」); –

+0

這個答案回答了這個問題。當然,還有許多其他方法取決於解決的問題。 –

+0

謝謝!正是我需要的。 Json.Net的SelectToken沒有我需要的功能。 –

2

對於那些不喜歡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; 
     } 


    } 


} 

用法:

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); 
}