gpt4 book ai didi

c# - 在 C# 中将过滤器与 JsonPath 一起使用

转载 作者:行者123 更新时间:2023-12-02 04:55:53 24 4
gpt4 key购买 nike

我正在使用 JsonPath for C#查询一些 JSON 数据。 JsonPath 没有自己的解析器,所以根据 Rick Sladkey's advice ,我正在使用 Json.NET将我的 Json 字符串解析为嵌套的 IDictionary 对象、IList 数组和基元的集合。然后我使用 JsonPath 对其进行过滤(在添加 Rick Sladkey's answer 中建议的类之后)。

作为引用,这里是我的代码中实际处理所有这些的部分:

// string exampleJsonString defined below
string query = "$.store.book[*].title" // we should get a list of all titles

// step 1: use Json.NET to parse the json string into a JObject
JObject parsedJson = JObject.Parse(exampleJsonString);

// step 2: use JsonPath with a custom ValueSystem (JsonNetValueSystem)
JsonPathContext context = new JsonPathContext
{ ValueSystem = new JsonNetValueSystem() };

// step 3: get results using JsonPath
List<object> toRet = context.SelectNodes(parsedJson,
query).Select(node => node.Value).ToList();

我最初使用 JsonPath 的原因是因为它的过滤器功能。您不仅可以执行像 "$.store.book[*].title" 这样的普通查询(以获取书店中所有书名的数组),还可以像 "这样的查询$.store.book[?(@.category == 'fiction')].title"(获取书店中类别与'fiction'匹配的所有书名的数组)。我需要能够将整个查询作为字符串传递,因此能够在查询时进行过滤非常有用。

不幸的是,我在使用此过滤器功能时遇到了一些问题。我希望我必须对 JsonNetValueSystem 类(最初在 the aforementioned stack overflow answer 中定义)或 JsonPath 命名空间(您可以从 JsonPath's google code page 获取 JsonPath.cs)进行调整。如果有一些外部工具或 Json.NET 的替代解析机制允许我保持 JsonPath 的过滤而不必编写太多额外的代码,那将是理想的,但我很确定我必须改变 JsonNetValueSystem或 JsonPath 本身。 (这两个都相当容易更改,因为它们只是 .cs 文件,但如果不做更多工作,我无法真正深入研究 Json.NET。)

我似乎无法弄清楚原始 JsonPath 代码在何处处理过滤,也无法弄清楚为什么 JsonNetValueSystem 类会剥夺它的该功能。非常感谢有关如何在查询字符串中添加过滤功能的任何建议。即使只是“不要弄乱 JsonPath,只需更改 JsonNetValueSystem”,反之亦然。

string exampleJsonString = "{
"store": {
"book": [ {
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
}, {
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}, {
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}, {
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
} ],
"bicycle": [ {
"color": "red",
"price": 19.95,
"style": [ "city", "hybrid" ]
}, {
"color": "blue",
"price": 59.91,
"style": [ "downhill", "freeride" ]
} ]
}
}"

最佳答案

当您在查询中使用脚本表达式时(?(...) 部分),您需要提供一个ScriptEvaluator 方法来评估脚本。不幸的是,他们没有为 C# 版本提供默认实现。您需要提供该实现。

开箱即用,这不是要解决的最微不足道的问题,您需要编写一个解释器。您有几个选择:使用 CodeDOM 将脚本编译并执行为 C# 代码(或您喜欢的任何语言),使用 Roslyn 解析脚本并进行评估,任何可行的方法。

对于这种特殊情况,一个快速而肮脏的解决方案是在您的脚本评估器方法中执行类似的操作:

object EvaluateScript(string script, object value, string context)
{
if (script == "@.category == 'fiction'")
{
var obj = value as JObject;
return (string)obj["category"] == "fiction";
}
return null;
}

这是另一个利用 IronPython 评估脚本的解决方案。

public class IronPythonScriptEvaluator
{
private Lazy<ScriptEngine> engine = new Lazy<ScriptEngine>(() => Python.CreateEngine());
private ScriptEngine Engine { get { return engine.Value; } }

private const string ItemName = "_IronPythonScriptEvaluator_item";

public object EvaluateScript(string script, object value, string context)
{
var cleanScript = CleanupScript(script);
var scope = Engine.CreateScope();
scope.SetVariable(ItemName, value);
return Engine.Execute<bool>(cleanScript, scope);
}

private string CleanupScript(string script)
{
return Regex.Replace(script, @"@", ItemName);
}
}

关于c# - 在 C# 中将过滤器与 JsonPath 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17998614/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com