Script to traverse and print types (except one with null values) and change values to attribute names (useful for testing purposes)
DECLARE
l_clob CLOB;
l_json json_object_t;
l_number NUMBER := 1;
FUNCTION process_object(p_json json_object_t, p_level NUMBER := 0, p_parent_object_name VARCHAR2 := NULL) RETURN json_object_t IS
l_keys JSON_KEY_LIST;
l_padding VARCHAR2(100):= LPAD(' ', p_level * 3, ' ');
l_result json_object_t := p_json;
BEGIN
l_keys := p_json.get_keys;
FOR i IN 1 .. l_keys.count LOOP
IF p_json.get(l_keys(i)).is_object THEN
dbms_output.put_line(l_padding || l_keys(i) || ' is object');
l_result.put(
l_keys(i),
process_object(TREAT(p_json.get(l_keys(i)) AS json_object_t), p_level + 1, LTRIM(p_parent_object_name || '.' || l_keys(i), '.'))
);
ELSIF p_json.get(l_keys(i)).is_number THEN
dbms_output.put_line(l_padding || l_keys(i) || ' is number');
l_result.put(l_keys(i), l_number);
l_number := l_number + 1;
--
ELSIF p_json.get(l_keys(i)).is_string THEN
dbms_output.put_line(l_padding || l_keys(i) || ' is string');
l_result.put(l_keys(i), LTRIM(p_parent_object_name || '_', '_') || l_keys(i));
ELSIF p_json.get(l_keys(i)).is_array THEN
dbms_output.put_line(l_padding || l_keys(i) || ' is array');
DECLARE
l_arr JSON_ARRAY_T := TREAT(p_json.get(l_keys(i)) AS JSON_ARRAY_T);
l_new_array JSON_ARRAY_T := NEW JSON_ARRAY_T;
BEGIN
FOR j IN 0 .. l_arr.get_size - 1 LOOP
IF l_arr.get(j).is_object THEN
l_new_array.append(
process_object(TREAT(l_arr.get(j) AS json_object_t), p_level + 1, LTRIM(p_parent_object_name || '.' || l_keys(i) || '[' || j || ']', '.'))
);
END IF;
-- check other types?
END LOOP;
l_result.put(l_keys(i), l_new_array);
END;
ELSE
dbms_output.put_line(l_padding || l_keys(i) || ' is unknown');
l_result.put(l_keys(i), LTRIM(p_parent_object_name || '_', '_') || l_keys(i));
END IF;
END LOOP;
RETURN l_result;
END;
BEGIN
l_json := json_object_t.parse(l_clob);
dbms_output.put_line( process_object(l_json).stringify );
END;
/