可以使用 JSONPath 进行不区分大小写的搜索吗?

2024-04-15

使用SelectToken method http://www.newtonsoft.com/json/help/html/SelectToken.htm#ID2RBToggleJSON.NET 来选择一个令牌JSONPath http://goessner.net/articles/JsonPath/,我发现没有办法指定搜索应该不区分大小写。

E.g.

json.SelectToken("$.maxAppVersion")

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

我的问题:

是否有官方方法或至少有解决方法以不区分大小写的方式使用 JSONPath?

(我发现的最接近的是这个类似的问题 https://stackoverflow.com/questions/6332651/gson-how-to-get-a-case-insensitive-element-from-json对于 JSON 的 Java 实现)


从版本 8.0.2 开始,这在 Json.NET 中尚未实现。

JSONPath 属性名称匹配是通过两个类完成的:FieldFilter https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JsonPath/FieldFilter.cs对于简单的名称匹配,以及ScanFilter https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JsonPath/ScanFilter.cs用于递归搜索。FieldFilter有以下代码,其中o is a JObject:

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

内部JObject https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JObject.cs uses a JPropertyKeyedCollection https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs保存其属性,这又使用以下比较器进行属性名称查找:

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

因此它区分大小写。相似地,ScanFilter has:

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

这也是区分大小写的。

中没有提到不区分大小写的匹配JSONPath 标准 http://goessner.net/articles/JsonPath/所以我认为你想要的东西根本无法开箱即用。

作为解决方法,您可以为此添加自己的扩展方法:

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 问题提供一种进行区分大小写的属性反序列化的方法 https://github.com/JamesNK/Newtonsoft.Json/issues/815它请求区分大小写的合同解析器以与 LINQ-to-JSON 的区分大小写保持一致。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可以使用 JSONPath 进行不区分大小写的搜索吗? 的相关文章

随机推荐