Как использовать пример C # с использованием JsonPath? - PullRequest
16 голосов
/ 24 сентября 2011

Я пытаюсь использовать JsonPath для .NET (http://code.google.com/p/jsonpath/downloads/list)), и мне не удается найти пример того, как проанализировать строку Json и строку JsonPath и получить результат.

Кто-нибудь использовал это?

Ответы [ 2 ]

23 голосов
/ 30 сентября 2011

Проблема, с которой вы столкнулись, заключается в том, что версия JsonPath на C # не включает в себя анализатор Json, поэтому вы должны использовать его с другой средой Json, которая обрабатывает сериализацию и десериализацию.

Способ работы JsonPath - использовать интерфейс с именем IJsonPathValueSystem для прохождения проанализированных объектов Json. JsonPath поставляется со встроенным BasicValueSystem, который использует интерфейс IDictionary для представления объектов Json и интерфейс IList для представления массивов Json.

Вы можете создавать свои собственные BasicValueSystem -совместимые объекты Json, создавая их с помощью инициализаторов коллекции C #, но это не очень полезно, когда ваш 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"]

Этот пример основан на образце Javascript на сайте JsonPath:

2 голосов
/ 03 декабря 2014

Для тех, кто не любит 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);
}
...