Home > OS >  Using a variable in JToken query
Using a variable in JToken query

Time:09-07

From the docs https://www.newtonsoft.com/json/help/html/SelectToken.htm

IEnumerable<JToken> price = o.SelectTokens("$..Products[?(@.Name == "AAA")].Price");

How could I re-write the above query where I have to find prices to match multiple product names from a list ["AAA", "BBB", "CCC"]

CodePudding user response:

Consider using SelectToken with LINQ in the same link you provided.

To achieve your goal, you can write something like:

var names = new string[]{"AAA", "BBB", "CCC"};
var prices = o.SelectTokens("$..Products[*]")
       .Where(p => names.Contains((string)p["Name"]))
       .Select(p => (decimal)p["Price"])
       .ToList();

CodePudding user response:

You may use the logical OR operator || in your JSONPath query:

var query = "$..Products[?(@.Name == 'AAA' || @.Name == 'BBB' || @.Name == 'CCC')].Price";
var prices = o.SelectTokens(query);

If you need to build the query from some runtime array of names, you may do so e.g. using LINQ as follows:

var names = new []{ "AAA", "BBB", "CCC" }; // Or whatever

var query = names.Select((n, i) => (n, i))
    .Aggregate(new StringBuilder("$..Products[?("), 
               (sb, p) => sb.Append(p.i == 0 ? "" : "||").Append("@.Name=='").Append(p.n).Append("'"))
    .Append(")].Price")
    .ToString();

var prices = o.SelectTokens(query);

Note that JToken.SelectToken() is intended to return a single token and will throw an exception if multiple tokens are matched. If you expect multiple tokens to be returned use JToken.SelectTokens().

Demo fiddle here.

  • Related