What is the correct syntax for a filter expression to query a JSON object with a specific attribute string value inside an array, using bracket notation?
I am limited to bracket notation because dot notation won't work in Delphi when there is a quote or apostrophe inside the filter expression.
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.
I've used an online JSON path evaluator against this JSON and come up with the expression result["elements"][?(@.name == 'Training Seminar - Nov 9')]
. In the online evaluator, this path works fine and returns the exact object I'm looking for. However, when I run it in Delphi I get an exception that says
EJSONPathException: Invalid index for array: ?(@.name == 'Training Seminar - Nov 9')
My question is, what is the correct syntax for a filter expression to query a JSON object with a specific attribute string value inside an array, using bracket notation?
MCVE for this as a console application, including the 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.