Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(json_value), | intent(in), | pointer | :: | me | ||
character(kind=CK,len=*), | intent(in) | :: | path | |||
type(json_value), | intent(out), | pointer | :: | p | ||
logical(kind=LK), | intent(out), | optional | :: | found | true if it was found |
Returns the json_value pointer given the path string.
type(json_value),pointer :: dat,p logical :: found !... call json_get(dat,'data(2).version',p,found)
The following special characters are used to denote paths:
$ - root @ - this . - child object member [] or () - child array element
Thus, if any of these characters are present in the name key, this routine cannot be used to get the value. In that case, the json_get_child routines would need to be used.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
character(kind=CK,len=1), | public, | parameter | :: | start_array_alt | = | '(' | |
character(kind=CK,len=1), | public, | parameter | :: | end_array_alt | = | ')' | |
integer(kind=IK), | public | :: | i | ||||
integer(kind=IK), | public | :: | length | ||||
integer(kind=IK), | public | :: | child_i | ||||
character(kind=CK,len=1), | public | :: | c | ||||
logical(kind=LK), | public | :: | array | ||||
type(json_value), | public, | pointer | :: | tmp |
subroutine json_get_by_path(me, path, p, found)
implicit none
type(json_value),pointer,intent(in) :: me
character(kind=CK,len=*),intent(in) :: path
type(json_value),pointer,intent(out) :: p
logical(LK),intent(out),optional :: found !! true if it was found
character(kind=CK,len=1),parameter :: start_array_alt = '('
character(kind=CK,len=1),parameter :: end_array_alt = ')'
integer(IK) :: i,length,child_i
character(kind=CK,len=1) :: c
logical(LK) :: array
type(json_value),pointer :: tmp
if (.not. exception_thrown) then
nullify(p)
! default to assuming relative to this
p => me
child_i = 1
array = .false.
length = len_trim(path)
do i=1, length
c = path(i:i)
select case (c)
case (CK_'$')
! root
do while (associated (p%parent))
p => p%parent
end do
child_i = i + 1
case (CK_'@')
! this
p => me
child_i = i + 1
case (CK_'.')
! get child member from p
if (child_i < i) then
nullify(tmp)
call json_get_child(p, path(child_i:i-1), tmp)
p => tmp
nullify(tmp)
else
child_i = i + 1
cycle
end if
if (.not. associated(p)) then
call throw_exception('Error in json_get_by_path:'//&
' Error getting child member.')
exit
end if
child_i = i+1
case (start_array,start_array_alt)
!....Modified to allow for 'var[3]' style syntax
!Note: jmozmoz/fson has a slightly different version of this...
! start looking for the array element index
array = .true.
! get child member from p
if (child_i < i) then
nullify(tmp)
call json_get_child(p, path(child_i:i-1), tmp)
p => tmp
nullify(tmp)
else
child_i = i + 1
cycle
end if
if (.not. associated(p)) then
call throw_exception('Error in json_get_by_path:'//&
' Error getting array element')
exit
end if
child_i = i + 1
case (end_array,end_array_alt)
if (.not.array) then
call throw_exception('Error in json_get_by_path: Unexpected ]')
exit
end if
array = .false.
child_i = string_to_integer(path(child_i:i-1))
nullify(tmp)
call json_get_child(p, child_i, tmp)
p => tmp
nullify(tmp)
child_i= i + 1
end select
end do
if (exception_thrown) then
if (present(found)) then
found = .false.
call json_clear_exceptions()
end if
else
! grab the last child if present in the path
if (child_i <= length) then
nullify(tmp)
call json_get_child(p, path(child_i:i-1), tmp)
p => tmp
nullify(tmp)
end if
if (associated(p)) then
if (present(found)) found = .true. !everything seems to be ok
else
call throw_exception('Error in json_get_by_path:'//&
' variable not found: '//trim(path))
if (present(found)) then
found = .false.
call json_clear_exceptions()
end if
end if
end if
else
if (present(found)) found = .false.
end if
end subroutine json_get_by_path