繁体   English   中英

如何使用 JsonPath 使用 C# 示例?

[英]How to use C# example using 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 以字符串形式从远程服务器BasicValueSystem ,这没有多大用处。

因此,如果您可以采用 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 数据集 + 示例的数据集和示例

我的 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");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM