@@ -7745,17 +7745,22 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
77457745 ! ! (otherwise use `json%path_separator`)
77467746 ! ! (only used if `path_mode=1`)
77477747
7748- type (json_value),pointer :: tmp ! ! for traversing the structure
7749- type (json_value),pointer :: element ! ! for traversing the structure
7750- integer (IK) :: var_type ! ! JSON variable type flag
7751- character (kind= CK,len= :),allocatable :: name ! ! variable name
7752- character (kind= CK,len= :),allocatable :: parent_name ! ! variable's parent name
7753- character (kind= CK,len= max_integer_str_len) :: istr ! ! for integer to string conversion
7754- ! ! (array indices)
7755- integer (IK) :: i ! ! counter
7756- integer (IK) :: n_children ! ! number of children for parent
7757- logical (LK) :: use_brackets ! ! to use '[]' characters for arrays
7758- logical (LK) :: parent_is_root ! ! if the parent is the root
7748+ character (kind= CK,len= :),allocatable :: name ! ! variable name
7749+ character (kind= CK,len= :),allocatable :: parent_name ! ! variable's parent name
7750+ character (kind= CK,len= max_integer_str_len) :: istr ! ! for integer to string conversion
7751+ ! ! (array indices)
7752+ type (json_value),pointer :: tmp ! ! for traversing the structure
7753+ type (json_value),pointer :: element ! ! for traversing the structure
7754+ integer (IK) :: var_type ! ! JSON variable type flag
7755+ integer (IK) :: tmp_var_type ! ! JSON variable type flag
7756+ integer (IK) :: i ! ! counter
7757+ integer (IK) :: n_children ! ! number of children for parent
7758+ logical (LK) :: use_brackets ! ! to use '[]' characters for arrays
7759+ logical (LK) :: parent_is_root ! ! if the parent is the root
7760+ character (kind= CK,len= 1 ) :: array_start ! ! for `path_mode=1`, the character to start arrays
7761+ character (kind= CK,len= 1 ) :: array_end ! ! for `path_mode=1`, the character to end arrays
7762+ logical :: consecutive_arrays ! ! check for array of array case
7763+ integer (IK) :: parents_parent_var_type ! ! `var_type` for parent's parent
77597764
77607765 ! optional input:
77617766 if (present (use_alt_array_tokens)) then
@@ -7764,6 +7769,19 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
77647769 use_brackets = .true.
77657770 end if
77667771
7772+ if (json% path_mode== 1_IK ) then
7773+ if (use_brackets) then
7774+ array_start = start_array
7775+ array_end = end_array
7776+ else
7777+ array_start = start_array_alt
7778+ array_end = end_array_alt
7779+ end if
7780+ end if
7781+
7782+ ! initialize:
7783+ consecutive_arrays = .false.
7784+
77677785 if (associated (p)) then
77687786
77697787 ! traverse the structure via parents up to the root
@@ -7787,6 +7805,13 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
77877805 if (json% path_mode== 2_IK ) then
77887806 parent_name = encode_rfc6901(parent_name)
77897807 end if
7808+ if (associated (tmp% parent% parent)) then
7809+ call json% info(tmp% parent% parent,var_type= parents_parent_var_type)
7810+ consecutive_arrays = parents_parent_var_type == json_array .and. &
7811+ var_type == json_array
7812+ else
7813+ consecutive_arrays = .false.
7814+ end if
77907815
77917816 select case (var_type)
77927817 case (json_array)
@@ -7816,36 +7841,52 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
78167841 ! example: `$['key'][1]`
78177842 ! [note: this uses 1-based indices]
78187843 call integer_to_string(i,int_fmt,istr)
7819- call add_to_path(start_array// single_quote// parent_name// &
7820- single_quote// end_array// &
7821- start_array// trim (adjustl (istr))// end_array,CK_' ' )
7844+ if (consecutive_arrays) then
7845+ call add_to_path(start_array// trim (adjustl (istr))// end_array,CK_' ' )
7846+ else
7847+ call add_to_path(start_array// single_quote// parent_name// &
7848+ single_quote// end_array// &
7849+ start_array// trim (adjustl (istr))// end_array,CK_' ' )
7850+ end if
78227851 case (2_IK )
78237852 ! rfc6901
7853+ ! Example: '/key/0'
78247854 call integer_to_string(i-1_IK ,int_fmt,istr) ! 0-based index
7825- call add_to_path(parent_name// slash// trim (adjustl (istr)))
7855+ if (consecutive_arrays) then
7856+ call add_to_path(trim (adjustl (istr)))
7857+ else
7858+ call add_to_path(parent_name// slash// trim (adjustl (istr)))
7859+ end if
78267860 case (1_IK )
78277861 ! default
7862+ ! Example: `key[1]`
78287863 call integer_to_string(i,int_fmt,istr)
7829- if (use_brackets) then
7830- call add_to_path(parent_name// start_array// &
7831- trim (adjustl (istr))// end_array,path_sep)
7864+ if (consecutive_arrays) then
7865+ call add_to_path(array_start// trim (adjustl (istr))// array_end,path_sep)
78327866 else
7833- call add_to_path(parent_name// start_array_alt // &
7834- trim (adjustl (istr))// end_array_alt ,path_sep)
7867+ call add_to_path(parent_name// array_start // &
7868+ trim (adjustl (istr))// array_end ,path_sep)
78357869 end if
78367870 end select
7837- tmp = > tmp% parent ! already added parent name
7871+
7872+ if (.not. consecutive_arrays) tmp = > tmp% parent ! already added parent name
78387873
78397874 case (json_object)
78407875
7841- ! process parent on the next pass
7842- select case (json% path_mode)
7843- case (3_IK )
7844- call add_to_path(start_array// single_quote// name// &
7845- single_quote// end_array,CK_' ' )
7846- case default
7847- call add_to_path(name,path_sep)
7848- end select
7876+ if (.not. consecutive_arrays) then
7877+ ! idea is not to print the array name if
7878+ ! it was already printed with the array
7879+
7880+ ! process parent on the next pass
7881+ select case (json% path_mode)
7882+ case (3_IK )
7883+ call add_to_path(start_array// single_quote// name// &
7884+ single_quote// end_array,CK_' ' )
7885+ case default
7886+ call add_to_path(name,path_sep)
7887+ end select
7888+
7889+ end if
78497890
78507891 case default
78517892
@@ -7914,7 +7955,7 @@ subroutine add_to_path(str,path_sep)
79147955 ! ! prepend the string to the path
79157956 implicit none
79167957 character (kind= CK,len=* ),intent (in ) :: str ! ! string to prepend to `path`
7917- character (kind= CK,len=* ),intent (in ),optional :: path_sep
7958+ character (kind= CK,len= 1 ),intent (in ),optional :: path_sep
79187959 ! ! path separator (default is '.').
79197960 ! ! (ignored if `json%path_mode/=1`)
79207961
@@ -7938,12 +7979,20 @@ subroutine add_to_path(str,path_sep)
79387979 if (.not. allocated (path)) then
79397980 path = str
79407981 else
7941- if (present (path_sep)) then
7942- ! use user specified:
7943- path = str// path_sep// path
7982+ ! shouldn't add the path_sep for cases like x[1][2]
7983+ ! [if current is an array element, and the previous was
7984+ ! also an array element] so check for that here:
7985+ if (.not. ( str(len (str):len (str))==array_end .and. &
7986+ path(1 :1 )==array_start )) then
7987+ if (present (path_sep)) then
7988+ ! use user specified:
7989+ path = str// path_sep// path
7990+ else
7991+ ! use the default:
7992+ path = str// json% path_separator// path
7993+ end if
79447994 else
7945- ! use the default:
7946- path = str// json% path_separator// path
7995+ path = str// path
79477996 end if
79487997 end if
79497998 end select
0 commit comments