2011-07-22 29 views
25

Tôi hiện đang làm việc trên một dự án Android yêu cầu tôi gọi một dịch vụ web sẽ trả lại cho tôi tệp json. Tôi đã sử dụng thư viện GSON để phân tích tất cả các tệp json và nhận được một đối tượng JSON. Nó đã được làm việc tốt cho đến khi tôi đi qua dữ liệu json này mà các lĩnh vực chính là năng động. Một ví dụ về tập tin này là như sau:Sử dụng GSON để phân tích cú pháp JSON với "khóa" và "giá trị" động trong android

{ "0": { "count":"5"}, 
    "1": { "title":"...", "desc":"" }, 
    "2": { "title":"...", "desc":"" }, 
    "3": { "title":"...", "desc":"" }, 
    "4": { "title":"...", "desc":"" }, 
    "5": { "title":"...", "desc":"" }, 
    "routes": { "route1":"...", "route3":"" }, 
} 

tôi có thể lấy số liệu dựa trên id chính của "0", nhưng tôi không chắc chắn làm thế nào để tận dụng giá trị này để có được những khác các đối tượng chính (id khóa 1-5), bao gồm dữ liệu mà tôi cần. Sẽ thực sự đánh giá cao nếu có ai có thể giúp tôi trong vấn đề này. Cảm ơn.

+0

Tôi muốn thêm rằng nếu bản đồ của bạn không được lồng vào nhau thì mọi thứ đơn giản hơn nhiều http://stackoverflow.com/questions/2779251/ how-can-i-convert-json-to-a-hashmap-using-gson –

Trả lời

30

Cách tiếp cận đơn giản nhất tôi có thể nghĩ là xử lý cấu trúc là Map (của Map).

Với Gson, điều này tương đối dễ thực hiện, miễn là cấu trúc Map được biết đến tĩnh, mọi chi nhánh từ gốc đều có cùng độ sâu và mọi thứ đều là String.

import java.io.FileReader; 
import java.lang.reflect.Type; 
import java.util.Map; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class GsonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    Type mapType = new TypeToken<Map<String,Map<String, String>>>() {}.getType(); 
    Map<String,Map<String, String>> map = gson.fromJson(new FileReader("input.json"), mapType); 
    System.out.println(map); 

    // Get the count... 
    int count = Integer.parseInt(map.get("0").get("count")); 

    // Get each numbered entry... 
    for (int i = 1; i <= count; i++) 
    { 
     System.out.println("Entry " + i + ":"); 
     Map<String, String> numberedEntry = map.get(String.valueOf(i)); 
     for (String key : numberedEntry.keySet()) 
     System.out.printf("key=%s, value=%s\n", key, numberedEntry.get(key)); 
    } 

    // Get the routes... 
    Map<String, String> routes = map.get("routes"); 

    // Get each route... 
    System.out.println("Routes:"); 
    for (String key : routes.keySet()) 
     System.out.printf("key=%s, value=%s\n", key, routes.get(key)); 
    } 
} 

Đối xử lý Map cấu trúc năng động hơn, tôi đề nghị chuyển sang sử dụng Jackson, thay vì Gson, như Jackson sẽ deserialize bất kỳ đối tượng JSON của bất kỳ phức tạp tùy ý vào một Java Map, chỉ với một dòng mã đơn giản, và nó sẽ tự động giữ lại các loại giá trị nguyên thủy.

import java.io.File; 
import java.util.Map; 

import org.codehaus.jackson.map.ObjectMapper; 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    ObjectMapper mapper = new ObjectMapper(); 
    Map map = mapper.readValue(new File("input.json"), Map.class); 
    System.out.println(map); 
    } 
} 

Điều tương tự cũng có thể đạt được với Gson, nhưng nó đòi hỏi hàng tá dòng mã. (Plus, Gson có những thiếu sót khác làm cho việc chuyển sang Jackson cũng xứng đáng với nó.)

+0

Xin chào, cảm ơn vì giải pháp của bạn! Nó hoạt động hoàn hảo. =) – Philip

+2

Trong Gson hiện tại công trình này: Bản đồ jsondata = g.fromJson (injson, Map.class); – Teddy

1

Bạn chỉ có thể nhận các đối tượng khóa riêng lẻ bằng cách sử dụng số lượng. Vì vậy, bạn sẽ nhận được đối tượng "1" và sau đó nhận được đối tượng "tiêu đề" và "desc" của nó, sau đó đối tượng "2" v.v.

+1

Tôi đã giải quyết được vấn đề của mình bằng cách sử dụng giải pháp của Bruce. Cảm ơn sự giúp đỡ của bạn anyway. =) – Philip

Các vấn đề liên quan