Using the SelectToken method of JSON.NET to select a token with JSONPath, I found no way to specifiy that the search should be case-insensitive.
E.g.
jso
This is not implemented in Json.NET as of version 8.0.2.
JSONPath property name matching is done with two classes: FieldFilter for simple name matches, and ScanFilter for recursive searches. FieldFilter
has the following code, where o
is a JObject
:
JToken v = o[Name];
if (v != null)
{
yield return v;
}
Internally JObject uses a JPropertyKeyedCollection to hold its properties, which in turn uses the following comparer for property name lookups:
private static readonly IEqualityComparer Comparer = StringComparer.Ordinal;
It is thus case-sensitive. Similarly, ScanFilter
has:
JProperty e = value as JProperty;
if (e != null)
{
if (e.Name == Name)
{
yield return e.Value;
}
}
Which is also case sensitive.
There's no mention of case-insensitive matching in the JSONPath standard so I think what you want simply isn't available out of the box.
As a workaround, you could add your own extension methods for this:
public static class JsonExtensions
{
public static IEnumerable CaseSelectPropertyValues(this JToken token, string name)
{
var obj = token as JObject;
if (obj == null)
yield break;
foreach (var property in obj.Properties())
{
if (name == null)
yield return property.Value;
else if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase))
yield return property.Value;
}
}
public static IEnumerable CaseSelectPropertyValues(this IEnumerable tokens, string name)
{
if (tokens == null)
throw new ArgumentNullException();
return tokens.SelectMany(t => t.CaseSelectPropertyValues(name));
}
}
And then chain them together with standard SelectTokens
calls, for instance:
var root = new { Array = new object[] { new { maxAppVersion = "1" }, new { MaxAppVersion = "2" } } };
var json = JToken.FromObject(root);
var tokens = json.SelectTokens("Array[*]").CaseSelectPropertyValues("maxappversion").ToList();
if (tokens.Count != 2)
throw new InvalidOperationException(); // No exception thrown
(Relatedly, see the Json.NET issue Provide a way to do case-sensitive property deserialization which requests a case-sensitive contract resolver for consistency with the case-sensitivity of LINQ-to-JSON.)