2016-02-29 432 views
3

使用JSON.NET的SelectToken method来选择带有JSONPath的令牌,我发现没有办法指定搜索应区分大小写。可能使用JSONPath搜索不区分大小写的内容?

E.g.

json.SelectToken("$.maxAppVersion") 

应该返回匹配的令牌,它无论是否写入maxappversionMAXAPPVERSION或任何其他外壳。

我的问题:

是否有一个正式的方式,或者至少一个变通办法在不区分大小写的方式来使用JSONPath?

(我发现的最接近是this similar question的Java实现的JSON)

回答

4

这不是在Json.NET实现的8.0.2版本。

JSONPath属性名称匹配由两个类完成:简单名称匹配的FieldFilter和递归搜索的ScanFilterFieldFilter具有下面的代码,其中oJObject

JToken v = o[Name]; 
if (v != null) 
{ 
    yield return v; 
} 

内部JObject使用JPropertyKeyedCollection保持其性能,这反过来使用以下比较器的属性名称查找:

private static readonly IEqualityComparer<string> Comparer = StringComparer.Ordinal; 

这是因此区分大小写。同样,ScanFilter有:

JProperty e = value as JProperty; 
if (e != null) 
{ 
    if (e.Name == Name) 
    { 
     yield return e.Value; 
    } 
} 

这也是区分大小写的。

JSONPath standard中没有提及不区分大小写的匹配,所以我认为你想要的仅仅是不可用的。

作为一种变通方法,您可以添加自己的扩展方法是:

public static class JsonExtensions 
{ 
    public static IEnumerable<JToken> 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<JToken> CaseSelectPropertyValues(this IEnumerable<JToken> tokens, string name) 
    { 
     if (tokens == null) 
      throw new ArgumentNullException(); 
     return tokens.SelectMany(t => t.CaseSelectPropertyValues(name)); 
    } 
} 

,然后以标准SelectTokens电话把它们结合在一起,例如:

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 

(与此相关的,请参阅Json.NET问题Provide a way to do case-sensitive property deserialization,它要求区分大小写的合约解析程序与LINQ-to-JSON的区分大小写一致)。