@@ -7745,17 +7745,22 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
7745
7745
! ! (otherwise use `json%path_separator`)
7746
7746
! ! (only used if `path_mode=1`)
7747
7747
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
7759
7764
7760
7765
! optional input:
7761
7766
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)
7764
7769
use_brackets = .true.
7765
7770
end if
7766
7771
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
+
7767
7785
if (associated (p)) then
7768
7786
7769
7787
! 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)
7787
7805
if (json% path_mode== 2_IK ) then
7788
7806
parent_name = encode_rfc6901(parent_name)
7789
7807
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
7790
7815
7791
7816
select case (var_type)
7792
7817
case (json_array)
@@ -7816,36 +7841,52 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
7816
7841
! example: `$['key'][1]`
7817
7842
! [note: this uses 1-based indices]
7818
7843
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
7822
7851
case (2_IK )
7823
7852
! rfc6901
7853
+ ! Example: '/key/0'
7824
7854
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
7826
7860
case (1_IK )
7827
7861
! default
7862
+ ! Example: `key[1]`
7828
7863
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)
7832
7866
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)
7835
7869
end if
7836
7870
end select
7837
- tmp = > tmp% parent ! already added parent name
7871
+
7872
+ if (.not. consecutive_arrays) tmp = > tmp% parent ! already added parent name
7838
7873
7839
7874
case (json_object)
7840
7875
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
7849
7890
7850
7891
case default
7851
7892
@@ -7914,7 +7955,7 @@ subroutine add_to_path(str,path_sep)
7914
7955
! ! prepend the string to the path
7915
7956
implicit none
7916
7957
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
7918
7959
! ! path separator (default is '.').
7919
7960
! ! (ignored if `json%path_mode/=1`)
7920
7961
@@ -7938,12 +7979,20 @@ subroutine add_to_path(str,path_sep)
7938
7979
if (.not. allocated (path)) then
7939
7980
path = str
7940
7981
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
7944
7994
else
7945
- ! use the default:
7946
- path = str// json% path_separator// path
7995
+ path = str// path
7947
7996
end if
7948
7997
end if
7949
7998
end select
0 commit comments