关于解析:如何使用plsql pljson框架解析json树?

How to parse a json tree using plsql pljson framework?

我正在使用网络服务http://maps.google.com/maps/api/geocode/json?address=mysore在plsql代码中获取位置数据。我可以使用oracle中与json一起使用的帮助来访问第一级数据。但这为从json获取一级数据提供了帮助。

我需要进一步获取lat和lng值。有人可以帮我吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Location = {
 "bounds" : {
   "northeast" : {
     "lat" : 44.9483849,
     "lng" : -93.1261959
    },
   "southwest" : {
     "lat" : 44.9223829,
     "lng" : -93.200307
    }
  },
 "location" : {
   "lat" : 44.9330076,
   "lng" : -93.16290629999999
  },
 "location_type" :"APPROXIMATE",
 "viewport" : {
   "northeast" : {
     "lat" : 44.9483849,
     "lng" : -93.1261959
    },
   "southwest" : {
     "lat" : 44.9223829,
     "lng" : -93.200307
    }
  }
}

这是我的代码,用于从google maps api获取地址。我需要从响应中获取纬度,经度和formatted_address。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
CREATE OR REPLACE PROCEDURE geo_lat_long_addr_proc(
      ADDRESS     VARCHAR2 DEFAULT 'EUR')
     IS
      v_debug_mode        BOOLEAN := TRUE;
      v_req               UTL_HTTP.req;
      v_resp              UTL_HTTP.resp;
      v_msg               VARCHAR2(80);
      v_entire_msg        VARCHAR2(32767) := NULL;
      v_conversion_factor NUMBER;
      v_url               VARCHAR2(256) :=
              'http://maps.google.com/maps/api/geocode/json?address='||
              ADDRESS
              ;
    BEGIN

      v_req := UTL_HTTP.begin_request(url => v_url,
         method => 'GET');
      v_resp := UTL_HTTP.get_response(r => v_req);

      IF    v_debug_mode
      THEN
         DBMS_OUTPUT.put_line('HTTP Status Return code: '||
                         v_resp.status_code);
      END IF;

      BEGIN
         LOOP
           UTL_HTTP.read_text(r => v_resp,data => v_msg);
           v_entire_msg := v_entire_msg||v_msg;
         END LOOP;
      EXCEPTION
         WHEN  UTL_HTTP.end_of_body
         THEN  NULL;
      END;

      IF    v_debug_mode
      THEN  DBMS_OUTPUT.put_line(v_entire_msg);
      END IF;

      UTL_HTTP.end_response(r => v_resp);

    EXCEPTION
      WHEN  OTHERS
      THEN  RETURN;
    END geo_lat_long_addr_proc;
    /


这是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
DECLARE
  l_geo_data clob := '{
 "bounds" : {
   "northeast" : {
     "lat" : 44.9483849,
     "lng" : -93.1261959
    },
   "southwest" : {
     "lat" : 44.9223829,
     "lng" : -93.200307
    }
  },
 "location" : {
   "lat" : 44.9330076,
   "lng" : -93.16290629999999
  },
 "location_type" :"APPROXIMATE",
 "viewport" : {
   "northeast" : {
     "lat" : 44.9483849,
     "lng" : -93.1261959
    },
   "southwest" : {
     "lat" : 44.9223829,
     "lng" : -93.200307
    }
  }
}'
;

  l_geo_data_json json;
  l_bounds_json    json;
  l_northeast_json json;
  l_southwest_json json;

BEGIN
  l_geo_data_json := json(l_geo_data);  

  DBMS_OUTPUT.put_line('-- one way to do it...');
  l_bounds_json    := json(l_geo_data_json.get('bounds'));

  l_northeast_json := json(l_bounds_json.get('northeast'));
  DBMS_OUTPUT.put_line('bounds.northeast.lat:'||l_northeast_json.get('lat').get_number);
  DBMS_OUTPUT.put_line('bounds.northeast.lng:'||l_northeast_json.get('lng').get_number);

  l_southwest_json := json(l_bounds_json.get('southwest'));
  DBMS_OUTPUT.put_line('bounds.southwest.lat:'||l_southwest_json.get('lat').get_number);
  DBMS_OUTPUT.put_line('bounds.southwest.lng:'||l_southwest_json.get('lng').get_number);

  DBMS_OUTPUT.new_line();  
  DBMS_OUTPUT.put_line('-- another way is to use path method if you dont care about any specific attribute but just the one you need...');
  DBMS_OUTPUT.put_line('bounds.northeast.lat:'||l_geo_data_json.PATH('bounds.northeast.lat').get_number);
  DBMS_OUTPUT.put_line('bounds.southwest.lat:'||l_geo_data_json.PATH('bounds.southwest.lat').get_number);

  DBMS_OUTPUT.new_line();  
  DBMS_OUTPUT.put_line('-- getting the location_type');
  DBMS_OUTPUT.put_line('location_type:' || l_geo_data_json.get('location_type').get_string);

END;


我可以使用下面的pljson代码获取纬度,经度和位置数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 l_response_obj     json;
   l_resultObject   json;
   l_list           json_list;
   l_locationObject   json;
   l_geometryObject   json;

l_response_obj := json(l_entire_msg);
      l_list := json_list(l_response_obj.get ('results'));

  -- Grab the first item in the list
  l_resultObject := json(l_list.head);


  -- Show the location data
  l_geometryObject := json(l_resultObject.get ('geometry'));
  l_locationObject := json(l_geometryObject.get ('location'));
  -- dbms_output.put_line ('Lat = ' || locationObject.get ('lat').TO_CHAR ());
  -- dbms_output.put_line ('Lng = ' || locationObject.get ('lng').TO_CHAR ());

  p_o_lat := l_locationObject.get ('lat').TO_CHAR ();
  p_o_lng := l_locationObject.get ('lng').TO_CHAR ();
  p_o_formatted_addr :=
     l_resultObject.get ('formatted_address').TO_CHAR ();