Skip to content

Feature request: TJsonObject.GetPath should support nested array indexing (matrix[1][2]) #89

@bflorac

Description

@bflorac

Summary

TJsonObject.GetPath supports object navigation (a.b.c) and single-level array indexing (items[3]), but rejects nested array indexing such as matrix[1][2] or rows[0][3].name. Even when the underlying data exists and the path is unambiguous, the call raises EJsonCastException from PathError.

For JSON documents containing 2-D arrays (grids, matrices, tabular data, paginated rows-of-rows), this means callers can't use GetPath at all for that branch of the tree — they have to break navigation into multiple calls and lose the path API's convenience.

Where it fails

In TJsonObject.GetPath, after the closing ] is consumed, the code only handles two next-character cases:

if P^ = '.' then
begin
  Inc(P);
  Obj := Item.ObjectValue;
  Item := nil;
end
else if P^ = #0 then
begin
  // return array element
  Result.FData.FIntern := Item;
  Break;
end;

If P^ is [, neither branch is taken; the outer loop iterates with F = P pointing at [, the fast-forward immediately breaks (Ch in [#0, '[', '.']), so F = EndF, and PathError is raised.

Reproduction

var
  O: TJsonObject;
begin
  O := TJsonBaseObject.Parse('{ "matrix": [ [1, 2], [3, 4] ] }') as TJsonObject;
  try
    // works:
    Writeln(O.A['matrix'].A[1].I[0].ToString);   // "3"
    // fails — raises EJsonCastException:
    Writeln(O.Path['matrix[1][0]'].IntValue.ToString);
  finally
    O.Free;
  end;
end;

Suggested approach

After resolving Item from the inner ], if the next character is [, treat that element as the array to index into for the next iteration. Conceptually a "carry" variable holding the just-resolved array. The F = EndF guard (used to detect an empty name segment) needs to be relaxed when the current character is [, since the segment between ] and the next [ is legitimately empty.

If it'd help, I have a local implementation that does this; happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions