Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use C# example using JsonPath?

Tags:

c#

jsonpath

I'm trying to use JsonPath for .NET (http://code.google.com/p/jsonpath/downloads/list) and I'm having trouble finding an example of how to parse a Json string and a JsonPath string and get a result.

Has anyone used this?

like image 547
Niels Bosma Avatar asked Sep 24 '11 06:09

Niels Bosma


People also ask

How is C used?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C easy for beginners?

C language is simple and easy to learn. C is a machine independent language, which means a C program written one machine can run on another machine without requiring a code change. C is a compiler based language and it supports only useful features which makes the compilation of C file fast.

How can I start learning C language?

Get started with C. Official C documentation - Might be hard to follow and understand for beginners. Visit official C Programming documentation. Write a lot of C programming code - The only way you can learn programming is by writing a lot of code.


2 Answers

The problem you are experiencing is that the C# version of JsonPath does not include a Json parser so you have to use it with another Json framework that handles serialization and deserialization.

The way JsonPath works is to use an interface called IJsonPathValueSystem to traverse parsed Json objects. JsonPath comes with a built-in BasicValueSystem that uses the IDictionary interface to represent Json objects and the IList interface to represent Json arrays.

You can create your own BasicValueSystem-compatible Json objects by constructing them using C# collection initializers but this is not of much use when your Json is coming in in the form of strings from a remote server, for example.

So if only you could take a Json string and parse it into a nested structure of IDictionary objects, IList arrays, and primitive values, you could then use JsonPath to filter it! As luck would have it, we can use Json.NET which has good serialization and deserialization capabilities to do that part of the job.

Unfortunately, Json.NET does not deserialize Json strings into a format compatible with the BasicValueSystem. So the first task for using JsonPath with Json.NET is to write a JsonNetValueSystem that implements IJsonPathValueSystem and that understands the JObject objects, JArray arrays, and JValue values that JObject.Parse produces.

So download both JsonPath and Json.NET and put them into a C# project. Then add this class to that project:

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

Now with all three of these pieces we can write a sample JsonPath program:

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

which produces this output:

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

This example is based on the Javascript sample at the JsonPath site:

  • Javascript Usage and Example
like image 75
Rick Sladkey Avatar answered Oct 08 '22 20:10

Rick Sladkey


For those that don't like 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;
        }


    }


}

Usage:

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);
}
like image 45
Stefan Steiger Avatar answered Oct 08 '22 20:10

Stefan Steiger