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.