2016-02-29 125 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的區分大小寫一致)。