将过滤器表达式添加到 JSONIterator Find 函数调用
Adding a filter expression to a JSONIterator Find function call
过滤器表达式使用方括号表示法查询数组中具有特定属性字符串值的 JSON 对象的正确语法是什么?
我只能使用方括号表示法,因为当过滤器表达式中有引号或撇号时,点表示法在 Delphi 中不起作用。
Use [] to access object properties that do contain a quoting character
in their name. For example, use root['child.name'] or
root["child.name"] to access the child.name property of the root
object.
我使用在线 JSON 路径评估器对此 JSON 进行了计算,并提出了表达式 result["elements"][?(@.name == 'Training Seminar - Nov 9')]
。在在线评估器中,此路径工作正常并且 returns 正是我正在寻找的对象。但是,当我 运行 它在 Delphi 中时,我得到一个异常
EJSONPathException: Invalid index for array: ?(@.name == 'Training
Seminar - Nov 9')
我的问题是,使用方括号表示法查询数组中具有特定属性字符串值的 JSON 对象的过滤器表达式的正确语法是什么?
MCVE 将此作为控制台应用程序,包括 JSON.
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes, System.JSON.Builders, System.JSON.Readers, System.JSON.Types;
const JsonStr = '{' +
' "result":{ ' +
' "elements":[ ' +
' { ' +
' "id":"ML_1HMloeUjEFgKaC9",' +
' "name":"Utilization Survey",' +
' },' +
' {' +
' "id":"ML_1zQjGtGXFPkEo6N",' +
' "name":"Training Seminar - Nov 9",' +
' }' +
' ]' +
' },' +
' "meta":{' +
' "httpStatus":"200 - OK",' +
' "requestId":"ef2afd6e-3fd9-4fdf-a8fe-c935c147a0af"' +
' }' +
'}';
procedure RunIt;
var Reader : TJsonTextReader;
Iterator : TJsonIterator;
StringReader : TStringReader;
Found : Boolean;
begin
StringReader := TStringReader.Create(JsonStr);
Reader := TJsonTextReader.Create(StringReader);
Iterator := TJsonIterator.Create(Reader);
try
Found := Iterator.Find('result["elements"][?(@.name == ''Training Seminar - Nov 9'')]');
//The value of Found is false or an exception is raised because of bad syntax in the filter expression
WriteLn(BoolToStr(Found));
ReadLn;
finally
Iterator.Free;
Reader.Free;
StringReader.Free;
end;
end;
begin
try
RunIt;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
Readln;
end
end;
end.
你根本不能使用表达式,因为它们没有实现。无论是点符号还是括号符号。摘自System.JSON.TJSONPathParser.
的官方文档
These operators do not support special expressions, they only
support actual values (object properties or array indexes).
不过在这种情况下,可以通过稍微复杂一点的方式来实现。
procedure RunIt;
var
lJSON, lValue, lName: TJSONValue;
lFound : Boolean;
begin
lFound := False;
lJSON := TJSONObject.ParseJSONValue(JsonStr);
if Assigned(lJSON) then
try
if lJSON.TryGetValue('result.elements', lValue) and (lValue is TJSONArray) then
begin
for lValue in TJSONArray(lValue) do
begin
lFound := lValue.TryGetValue('name', lName) and (lName.Value = 'Training Seminar - Nov 9');
if lFound then
Break;
end;
end;
finally
lJSON.Free;
end;
WriteLn(BoolToStr(lFound));
ReadLn;
end;
过滤器表达式使用方括号表示法查询数组中具有特定属性字符串值的 JSON 对象的正确语法是什么?
我只能使用方括号表示法,因为当过滤器表达式中有引号或撇号时,点表示法在 Delphi 中不起作用。
Use [] to access object properties that do contain a quoting character in their name. For example, use root['child.name'] or root["child.name"] to access the child.name property of the root object.
我使用在线 JSON 路径评估器对此 JSON 进行了计算,并提出了表达式 result["elements"][?(@.name == 'Training Seminar - Nov 9')]
。在在线评估器中,此路径工作正常并且 returns 正是我正在寻找的对象。但是,当我 运行 它在 Delphi 中时,我得到一个异常
EJSONPathException: Invalid index for array: ?(@.name == 'Training Seminar - Nov 9')
我的问题是,使用方括号表示法查询数组中具有特定属性字符串值的 JSON 对象的过滤器表达式的正确语法是什么?
MCVE 将此作为控制台应用程序,包括 JSON.
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes, System.JSON.Builders, System.JSON.Readers, System.JSON.Types;
const JsonStr = '{' +
' "result":{ ' +
' "elements":[ ' +
' { ' +
' "id":"ML_1HMloeUjEFgKaC9",' +
' "name":"Utilization Survey",' +
' },' +
' {' +
' "id":"ML_1zQjGtGXFPkEo6N",' +
' "name":"Training Seminar - Nov 9",' +
' }' +
' ]' +
' },' +
' "meta":{' +
' "httpStatus":"200 - OK",' +
' "requestId":"ef2afd6e-3fd9-4fdf-a8fe-c935c147a0af"' +
' }' +
'}';
procedure RunIt;
var Reader : TJsonTextReader;
Iterator : TJsonIterator;
StringReader : TStringReader;
Found : Boolean;
begin
StringReader := TStringReader.Create(JsonStr);
Reader := TJsonTextReader.Create(StringReader);
Iterator := TJsonIterator.Create(Reader);
try
Found := Iterator.Find('result["elements"][?(@.name == ''Training Seminar - Nov 9'')]');
//The value of Found is false or an exception is raised because of bad syntax in the filter expression
WriteLn(BoolToStr(Found));
ReadLn;
finally
Iterator.Free;
Reader.Free;
StringReader.Free;
end;
end;
begin
try
RunIt;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
Readln;
end
end;
end.
你根本不能使用表达式,因为它们没有实现。无论是点符号还是括号符号。摘自System.JSON.TJSONPathParser.
的官方文档These operators do not support special expressions, they only support actual values (object properties or array indexes).
不过在这种情况下,可以通过稍微复杂一点的方式来实现。
procedure RunIt;
var
lJSON, lValue, lName: TJSONValue;
lFound : Boolean;
begin
lFound := False;
lJSON := TJSONObject.ParseJSONValue(JsonStr);
if Assigned(lJSON) then
try
if lJSON.TryGetValue('result.elements', lValue) and (lValue is TJSONArray) then
begin
for lValue in TJSONArray(lValue) do
begin
lFound := lValue.TryGetValue('name', lName) and (lName.Value = 'Training Seminar - Nov 9');
if lFound then
Break;
end;
end;
finally
lJSON.Free;
end;
WriteLn(BoolToStr(lFound));
ReadLn;
end;