Checks a JSON object for duplicate child names.
It uses the specified settings for name matching (see name_strings_equal).
Note
This will only check for one duplicate, it will return the first one that it finds.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(json_core), | intent(inout) | :: | json | |||
type(json_value), | intent(in), | pointer | :: | p |
the object to search. If |
|
logical(kind=LK), | intent(out) | :: | has_duplicate |
true if there is at least
two children have duplicate
|
||
character(kind=CK, len=:), | intent(out), | optional, | allocatable | :: | name |
the duplicate name (unallocated if no duplicate was found) |
character(kind=CK, len=:), | intent(out), | optional, | allocatable | :: | path |
the full path to the duplicate name (unallocated if no duplicate was found) |
subroutine json_check_children_for_duplicate_keys(json,p,has_duplicate,name,path) implicit none class(json_core),intent(inout) :: json type(json_value),pointer,intent(in) :: p !! the object to search. If `p` is !! not a `json_object`, then `has_duplicate` !! will be false. logical(LK),intent(out) :: has_duplicate !! true if there is at least !! two children have duplicate !! `name` values. character(kind=CK,len=:),allocatable,intent(out),optional :: name !! the duplicate name !! (unallocated if no !! duplicate was found) character(kind=CK,len=:),allocatable,intent(out),optional :: path !! the full path to the !! duplicate name !! (unallocated if no !! duplicate was found) integer(IK) :: i !! counter integer(IK) :: j !! counter type(json_value),pointer :: child !! pointer to a child of `p` integer(IK) :: n_children !! number of children of `p` logical(LK) :: found !! flag for `get_child` type :: alloc_str !! so we can have an array of allocatable strings character(kind=CK,len=:),allocatable :: str !! name string end type alloc_str type(alloc_str),dimension(:),allocatable :: names !! array of all the !! child name strings ! initialize: has_duplicate =.false. if (.not. json%exception_thrown) then if (associated(p)) then if (p%var_type==json_object) then ! number of items to check: n_children = json%count(p) allocate(names(n_children)) ! first get a list of all the name keys: do i=1, n_children call json%get_child(p,i,child,found) ! get by index if (.not. found) then call json%throw_exception(& 'Error in json_check_children_for_duplicate_keys: '//& 'Malformed JSON linked list') exit end if if (allocated(child%name)) then names(i)%str = child%name else call json%throw_exception(& 'Error in json_check_children_for_duplicate_keys: '//& 'Object child name is not allocated') exit end if end do if (.not. json%exception_thrown) then ! now check the list for duplicates: main: do i=1,n_children do j=1,i-1 if (json%name_strings_equal(names(i)%str,names(j)%str)) then has_duplicate = .true. if (present(name)) then name = names(i)%str end if if (present(path)) then call json%get_child(p,names(i)%str,child,found) ! get by name if (found) then call json%get_path(child,path,found) if (.not. found) then ! should never happen since we know it is there call json%throw_exception(& 'Error in json_check_children_for_duplicate_keys: '//& 'Could not get path') end if else ! should never happen since we know it is there call json%throw_exception(& 'Error in json_check_children_for_duplicate_keys: '//& 'Could not get child: '//trim(names(i)%str)) end if end if exit main end if end do end do main end if ! cleanup do i=1,n_children if (allocated(names(i)%str)) deallocate(names(i)%str) end do if (allocated(names)) deallocate(names) end if end if end if end subroutine json_check_children_for_duplicate_keys