我正在尝试将 JsonPath 用于 .NET ( http://code.google.com/p/jsonpath/downloads/list ),但我无法找到如何解析 Json 字符串和 JsonPath 字符串的示例和得到一个结果。
有人用过这个吗?
我正在尝试将 JsonPath 用于 .NET ( http://code.google.com/p/jsonpath/downloads/list ),但我无法找到如何解析 Json 字符串和 JsonPath 字符串的示例和得到一个结果。
有人用过这个吗?
您遇到的问题是 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
对象、JArray
数组和JValue
值的程序JObject.Parse
。
因此,下载 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 示例:
对于那些不喜欢 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);
}
使用 Newtonsoft.Json.Linq 你可以使用函数 SelectToken 并尝试你的 JsonPath 检查文档https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
Object jsonObj = JObject.Parse(stringResult);
JToken pathResult = jsonObj.SelectToken("results[0].example");
return pathResult.ToString();
我发现只要不需要过滤,内部的 JavaScriptSerializer() 就可以正常工作。
我的 JsonPath 实现来源是GitHub
public static string SelectFromJson(string inputJsonData, string inputJsonPath)
{
// Use the serializer to deserialize the JSON but also to create the snippets
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
dynamic dynJson = serializer.Deserialize<object>(inputJsonData);
var jsonPath = new JsonPath.JsonPathContext();
var jsonResults = jsonPath.Select(dynJson, inputJsonPath);
var valueList = new List<string>();
foreach (var node in jsonResults)
{
if (node is string)
{
valueList.Add(node);
}
else
{
// If the object is too complex then return a list of JSON snippets
valueList.Add(serializer.Serialize(node));
}
}
return String.Join("\n", valueList);
}
该函数的使用如下。
var result = SelectFromJson(@"
{ ""store"": {
""book"": [
{ ""category"": ""fiction"",
""author"": ""J. R. R. Tolkien"",
""title"": ""The Lord of the Rings"",
""isbn"": ""0-395-19395-8"",
""price"": 22.99
}
]
}
}", "$.store.book[*].author");