Skip to content

Commit 55d689e

Browse files
committed
updated jsonpath bracket notation to allow for using single or double quotes for the keys.
1 parent 7e36f3d commit 55d689e

File tree

2 files changed

+60
-21
lines changed

2 files changed

+60
-21
lines changed

src/json_value_module.F90

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6213,12 +6213,16 @@ end subroutine json_get_by_path_rfc6901
62136213
! type(json_value),pointer :: dat,p
62146214
! logical :: found
62156215
! !...
6216+
! call json%initialize(path_mode=3)
6217+
62166218
! call json%get(dat,"$['store']['book'][1]['title']",p,found)
62176219
!````
62186220
!
62196221
! The first character `$` is optional, and signifies the root
6220-
! of the structure. If it is not present, the the first key is
6221-
! taken to be in the `me` object.
6222+
! of the structure. If it is not present, then the first key
6223+
! is taken to be in the `me` object.
6224+
!
6225+
! Single or double quotes may be used
62226226
!
62236227
!### See also
62246228
! * [[json_get_by_path_default]] - subset of JSONPath "dot-notation"
@@ -6230,7 +6234,12 @@ end subroutine json_get_by_path_rfc6901
62306234
!@note Uses 1-based array indices (same as [[json_get_by_path_default]],
62316235
! but unlike [[json_get_by_path_rfc6901]] which uses 0-based indices).
62326236
!
6233-
!@warning The `create` logic hasn't been added yet !!!
6237+
!@warning Note that if using single quotes, this routine cannot parse
6238+
! a key containing `']`. If using double quotes, this routine
6239+
! cannot parse a key containing `"]`. If the key contains both
6240+
! `']` and `"]`, there is no way to parse it using this routine.
6241+
!
6242+
!@warning The `create` logic hasn't been added yet !
62346243

62356244
subroutine json_get_by_path_jsonpath_bracket(json,me,path,p,found,create_it,was_created)
62366245

@@ -6267,6 +6276,9 @@ subroutine json_get_by_path_jsonpath_bracket(json,me,path,p,found,create_it,was_
62676276
!! traversing the structure
62686277
integer(IK) :: i !! counter
62696278
integer(IK) :: ilen !! length of `path` string
6279+
logical(LK) :: double_quotes !! if the keys are enclosed in `"`,
6280+
!! rather than `'` tokens.
6281+
62706282
logical(LK) :: create !! if the object is to be created
62716283
logical(LK) :: created !! if `create` is true, then this will be
62726284
!! true if the leaf object had to be created
@@ -6335,26 +6347,35 @@ subroutine json_get_by_path_jsonpath_bracket(json,me,path,p,found,create_it,was_
63356347

63366348
! get the next token by checking:
63376349
!
6338-
! * is the token after istart a quote?
6339-
! if so, then search for the next `']`
6340-
! ['']
6341-
!
6342-
! * if not, then maybe it is a number,
6343-
! so search for the next `]`
6344-
! [1]
6350+
! * [''] -- is the token after istart a quote?
6351+
! if so, then search for the next `']`
63456352
!
6346-
! istart iend
6347-
! | |
6348-
! [abcdefg][h][ijk]
6353+
! * [1] -- if not, then maybe it is a number,
6354+
! so search for the next `]`
63496355

63506356
! verify length of remaining string
63516357
if (istart+2<=ilen) then
6352-
if (path(istart+1:istart+1) == single_quote) then ! ['
6353-
istart = istart + 1 ! move to ' index
6354-
! it should be a key value
6355-
iend = istart + index(path(istart+1:ilen),&
6356-
single_quote//end_array) ! ']
6358+
6359+
double_quotes = path(istart+1:istart+1) == quotation_mark ! ["
6360+
6361+
if (double_quotes .or. path(istart+1:istart+1)==single_quote) then ! ['
6362+
6363+
! it might be a key value: ['abc']
6364+
6365+
istart = istart + 1 ! move counter to ' index
6366+
if (double_quotes) then
6367+
iend = istart + index(path(istart+1:ilen),&
6368+
quotation_mark//end_array) ! "]
6369+
else
6370+
iend = istart + index(path(istart+1:ilen),&
6371+
single_quote//end_array) ! ']
6372+
end if
63576373
if (iend>istart) then
6374+
6375+
! istart iend
6376+
! | |
6377+
! ['abcdefg']
6378+
63586379
if (iend>istart+1) then
63596380
token = path(istart+1:iend-1)
63606381
else
@@ -6376,15 +6397,18 @@ subroutine json_get_by_path_jsonpath_bracket(json,me,path,p,found,create_it,was_
63766397
'" in path: '//trim(path))
63776398
exit
63786399
end if
6379-
iend = iend + 1 ! move to ]
6400+
iend = iend + 1 ! move counter to ] index
63806401
else
63816402
call json%throw_exception(&
63826403
'Error in json_get_by_path_jsonpath_bracket: '//&
63836404
'invalid path: '//trim(path))
63846405
exit
63856406
end if
6407+
63866408
else
6387-
! it might be an integer value
6409+
6410+
! it might be an integer value: [123]
6411+
63886412
iend = istart + index(path(istart+1:ilen),end_array) ! ]
63896413
if (iend>istart+1) then
63906414

@@ -6434,7 +6458,9 @@ subroutine json_get_by_path_jsonpath_bracket(json,me,path,p,found,create_it,was_
64346458
'invalid path: '//trim(path))
64356459
exit
64366460
end if
6461+
64376462
end if
6463+
64386464
else
64396465
call json%throw_exception(&
64406466
'Error in json_get_by_path_jsonpath_bracket: '//&

src/tests/jf_test_1.f90

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,20 @@ subroutine test_1(error_cnt)
388388
call json%print_error_message(error_unit)
389389
error_cnt = error_cnt + 1
390390
else
391-
write(error_unit,'(A)') "['data'][1]['array'][2] = "//trim(cval)
391+
write(error_unit,'(A)') "$['data'][1]['array'][2] = "//trim(cval)
392+
end if
393+
! get a logical value (use double quotes):
394+
write(error_unit,'(A)') ''
395+
call json%get('$["data"][1]["tf1"]', lval)
396+
if (json%failed()) then
397+
call json%print_error_message(error_unit)
398+
error_cnt = error_cnt + 1
399+
else
400+
if (lval) then
401+
write(error_unit,'(A)') '$["data"][1]["tf1"] = True'
402+
else
403+
write(error_unit,'(A)') '$["data"][1]["tf1"] = False'
404+
end if
392405
end if
393406

394407
end if

0 commit comments

Comments
 (0)