可以使用JSONPath搜索不区分大小写的内容吗? [英] Possible to search case-insensitive with JSONPath?
问题描述
使用JSON.NET的 SelectToken
方法要使用 JSONPath 选择令牌,我发现没有办法指定搜索不区分大小写.
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.
例如
json.SelectToken("$.maxAppVersion")
无论返回的是maxappversion
,MAXAPPVERSION
还是任何其他大小写形式,都应返回匹配的令牌.
should return a matching token, no matter whether it is written maxappversion
, MAXAPPVERSION
or any other casing.
我的问题:
是否存在以不区分大小写的方式使用JSONPath的官方方法或至少一种变通方法?
Is there an official way or at least a work-around to use JSONPath in a case-insensitive way?
(我找到的最接近的是这个类似的问题(对于Java的JSON实现)
(The closest I found was this similar question for a Java implementation of JSON)
推荐答案
从8.0.2版开始,此功能尚未在Json.NET中实现.
This is not implemented in Json.NET as of version 8.0.2.
JSONPath属性名称匹配通过两个类完成: FieldFilter
用于简单的名称匹配,以及
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;
}
内部 JObject
使用 JPropertyKeyedCollection
保留其属性,该属性随后使用以下比较器进行属性名称查找:
Internally JObject
uses a JPropertyKeyedCollection
to hold its properties, which in turn uses the following comparer for property name lookups:
private static readonly IEqualityComparer<string> Comparer = StringComparer.Ordinal;
因此区分大小写.同样,ScanFilter
具有:
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.
JSONPath标准中没有提及不区分大小写的匹配,所以我认为您想要什么就是开箱即用.
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<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
调用链接在一起,例如:
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
(相关信息,请参见Json.NET问题提供一种区分大小写的方法属性反序列化,要求使用区分大小写的合同解析器,以确保与LINQ-to-JSON的区分大小写一致.)
(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.)
这篇关于可以使用JSONPath搜索不区分大小写的内容吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!