0

我需要评估某些表达式,并根据评估选择下一步。我正在尝试为此使用 JInt javscript 解释器。

对于来自 json 的基本评估,它工作正常。但是当我试图在数组上添加额外的操作时,问题就来了。

我的方法,为基础对象设置值 => 编写一个函数来评估表达式 => 调用这个函数并将表达式传递给评估 => 函数将使用 eval 来评估传递的字符串。初始对象已在前面的步骤中设置。

像这样的东西,

inputStart.Reference.CompanyCode == \"ABC\"

在此, inputStart 是我已经使用设置的基础对象

engine.SetValue("inputStart", JsonConvert.DeserializeObject(inputStart));

inputStart 是 json 文本。小提琴也有字符串供参考。最后是函数,

engine.Execute("function evaluateExpression(expression) { " +
                       "return eval(expression); " +
                       "}")
            .GetValue("evaluateExpression");

var test = engine.Invoke("evaluateExpression", "inputStart.Reference.CompanyCode == \"ABC\"");

此代码工作正常。现在的变化是,我有另一个包含数组的 json 文本。我正在尝试使用过滤器或查找来定位特定的数组项,然后对其进行一些操作。像这样的东西,

inputQuestions.Questions.filter((x) => x.Code == \"INIT_IMP\")[0].Answer.Answer.Code

这给了我以下错误,

未处理的异常。System.ArgumentException:使用无效键值访问的 JArray 值:“过滤器”。预期为 Int32 数组索引。

我的完整程序供参考,

string inputStart = "{\n\t\"PurposeCode\": \"START\",\n\t\"Reference\": {\n\t\t\"CompanyCode\": \"ABC\"\t\t\n\t}\n}";
string inputQuestions = "{\n\t\"QuestionSetCode\": \"QUES_SET_1\",\n\t\"Version\": 1,\n\t\"Questions\": [{\n\t\t\"Code\": \"INIT_IMP\",\n\t\t\"Text\": \"Impact ?\",\n\t\t\"AnswerType\": 3,\n\t\t\"SequenceNumber\": 1,\n\t\t\"Answer\": {\n\t\t\t\"Answers\": [{\n\t\t\t\t\"Code\": \"INIT_IMP_DO\",\n\t\t\t\t\"Text\": \"A\",\n\t\t\t\t\"SequenceNumber\": 1\n\t\t\t}, {\n\t\t\t\t\"Code\": \"INIT_IMP_DA\",\n\t\t\t\t\"Text\": \"B\",\n\t\t\t\t\"SequenceNumber\": 2\n\t\t\t}, {\n\t\t\t\t\"Code\": \"INIT_IMP_AO\",\n\t\t\t\t\"Text\": \"C\",\n\t\t\t\t\"SequenceNumber\": 3\n\t\t\t}],\n\t\t\t\"Answer\": {\n\t\t\t\t\"Code\": \"INIT_IMP_DO\",\n\t\t\t\t\"Text\": \"A\",\n\t\t\t\t\"SequenceNumber\": 1\n\t\t\t},\n\t\t\t\"Type\": \"ListOfValuesAnswer\"\n\t\t},\n\t\t\"Applicable\": true\n\t}, {\n\t\t\"Code\": \"ENT_ACC_LIQ\",\n\t\t\"Text\": \"Exposure ?\",\n\t\t\"AnswerType\": 3,\n\t\t\"SequenceNumber\": 2,\n\t\t\"Answer\": {\n\t\t\t\"Answers\": [{\n\t\t\t\t\"Code\": \"ENT_ACC_LIQ_Y\",\n\t\t\t\t\"Text\": \"Yes\",\n\t\t\t\t\"SequenceNumber\": 1\n\t\t\t}, {\n\t\t\t\t\"Code\": \"ENT_ACC_LIQ_N\",\n\t\t\t\t\"Text\": \"No\",\n\t\t\t\t\"SequenceNumber\": 2\n\t\t\t}],\n\t\t\t\"Answer\": {\n\t\t\t\t\"Code\": \"ENT_ACC_LIQ_N\",\n\t\t\t\t\"Text\": \"No\",\n\t\t\t\t\"SequenceNumber\": 2\n\t\t\t},\n\t\t\t\"Type\": \"ListOfValuesAnswer\"\n\t\t},\n\t\t\"Applicable\": true\n\t}],\n\t\"ClientId\": null\n}";
        
Engine engine = new Engine();
        
engine.SetValue("inputStart", JsonConvert.DeserializeObject(inputStart));
engine.SetValue("inputQuestions", JsonConvert.DeserializeObject(inputQuestions));
        
engine.Execute("function evaluateExpression(expression) { " +
                       "return eval(expression); " +
                       "}")
            .GetValue("evaluateExpression");

var test = engine.Invoke("evaluateExpression", "inputQuestions.Questions.filter((x) => x.Code == \"INIT_IMP\")[0].Answer.Answer.Code == \"INIT_IMP_DO\" && inputStart.Reference.CompanyCode == \"ABC\"");
        
Console.WriteLine(test);

这是我正在尝试做的完整小提琴,https://dotnetfiddle.net/GtamM8

如果有人遇到过这样的问题,或者可以提出解决方案,那将非常有帮助。

4

1 回答 1

0

因为您使用的是新的语言结构,所以您应该使用 NuGet 的 3.x 预览版。3.x 系列包含对 lambda 表达式和针对它们的数组过滤的支持。

于 2021-01-23T15:32:06.127 回答