繁体   English   中英

使用键值对将JSON对象转换为平面对象

[英]Convert JSON Object as a Flat Obejct with Key value pair

我得到一个JSON对象,看起来像:

{
    "id": "1",
    "name": "Hw",
    "price": {
        "value": "10"
    },
    {
        "items": [{
            "id": "1"
        }]
    }
}

我想将其表示为平面地图,但我想将项目数组表示为列表。

我的输出应如下所示:

{
"id": "1",
"name":"Hw",
"price":"10",
"items": ["1"]
}

有人可以建议我如何实现这一目标吗? 我尝试了这种方法:

如何将JSON反序列化为类似Map的扁平结构?

上述尝试链接的输出:

{
"id": "1",
"name":"Hw",
"price.value":"10",
"items[0].id": "1"
}

但这将数组值表示为我不需要的array[0]array[1] 我需要此数组作为列表。

您提供的JSON无效。 我认为是:

{
    "id": "1",
    "name": "Hw",
    "price": {
        "value": "10"
    },
    "items": [{
        "id": "1"
    }]
}

您所要提出的问题无法找到通用的解决方案。 但是对于这种特定的JSON,这可以做到(使用json-simple ):

@SuppressWarnings("unchecked")
public Map<String, String> transform(String inputJSON) throws ParseException {
    Map<String, String> result = new LinkedHashMap<>();
    JSONObject inputJSONObj = (JSONObject) new JSONParser().parse(inputJSON);
    String id = inputJSONObj.getOrDefault("id", "").toString();
    String name = inputJSONObj.getOrDefault("name", "").toString();
    String price = ((JSONObject) inputJSONObj.getOrDefault("price", new JSONObject())).getOrDefault("value", "")
            .toString();
    JSONArray itemsArray = (JSONArray) inputJSONObj.getOrDefault("items", new JSONArray());
    int n = itemsArray.size();
    String[] itemIDs = new String[n];
    for (int i = 0; i < n; i++) {
        JSONObject itemObj = (JSONObject) itemsArray.get(i);
        String itemId = itemObj.getOrDefault("id", "").toString();
        itemIDs[i] = itemId;
    }
    result.put("id", id);
    result.put("name", name);
    result.put("price", price);
    result.put("items", Arrays.toString(itemIDs));
    return result;
}

使用Gson的方法。 这正是您想要的“将其表示为平面地图,但我想将项目数组表示为列表”

public class ParseJson1 {
    public static void main (String[] args){
        Type type = new TypeToken<HashMap<String, Object>>() {
        }.getType();
        Gson gson = new Gson();
        String json = "{\n" +
                "           \"id\": \"1\",\n" +
                "           \"name\": \"Hw\", \n" +
                "           \"price\": {\n" +
                "               \"value\": \"10\"\n" +
                "           },\n" +
                "           \"items\": [{\n" +
                "               \"id\": \"1\"\n" +
                "           }]\n" +
                "      }\n";
        HashMap<String, Object> map = gson.fromJson(json, type);
        Object val = null;
        for(String key : map.keySet()){
            val = map.get(key);
            if(val instanceof List){
                for(Object s : (List)val){
                    System.out.println(key + ":" + s);
                }
            } else 
            System.out.println(key + ":" + map.get(key));
        }
    }
}

您必须在地图集合Map<String, String>中转换您的Map<String, String>这将帮助您将Map Array转换为JSON格式。

JSONObject jsonObject = new JSONObject();
Map<String, String> mapObject = new HashMap<String, String>();
mapObject.put("id", "1");
mapObject.put("name", "VBage");
mapObject.put("mobile", "654321");

jsonObject.put("myJSON", mapObject);
System.out.println(jsonObject.toString());

首先,JSON似乎没有正确的格式。 你是这个意思吗

{
    "id": "1",
    "name": "Hw",
    "price": {
        "value": "10"
    },
    "items": [{
        "id": "1"
    }]
}

另外,由于您要附加( 如何将JSON反序列化为类似Map的扁平结构? )的链接,因此我假设您希望以相同的方式展平JSON,结果应为

{
   id=1,
   name=Hw,
   price.value=10,
   items[0]=1,
}

另外,如果您只想让项目返回ID列表(即“ items”:[“ 1”]),那么获取以下内容的JSON更合乎逻辑

{
    "id": "1",
    "name": "Hw",
    "price": {
        "value": "10"
    },
    "items": [ "1" ] // instead of "items": [{"id": "1"}]

}

您已附加的链接( 如何将JSON反序列化为类似Map的平面结构? )提供了一个通用解决方案,无需进行任何自定义。 它不应该知道“ id”是要附加在项目上的值。

因此,我的第一个建议是将JSON更改"items": [ "1" ]

如果由于某种原因无法更改JSON,则需要进行一些自定义 ,如下所示:

import org.codehaus.jackson.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.ValueNode;
import org.junit.Test;

public class Main {
    String json = "{\n" +
            "           \"id\": \"1\",\n" +
            "           \"name\": \"Hw\", \n" +
            "           \"price\": {\n" +
            "               \"value\": \"10\"\n" +
            "           },\n" +
            "           \"items\": [{\n" +
            "               \"id\": \"1\"\n" +
            "           }]\n" +
            "      }\n";

    @Test
    public void testCreatingKeyValues() {
        Map<String, String> map = new HashMap<String, String>();
        try {
            addKeys("", new ObjectMapper().readTree(json), map);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(map);
    }

    private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map) {
        if (jsonNode.isObject()) {
            ObjectNode objectNode = (ObjectNode) jsonNode;
            Iterator<Map.Entry<String, JsonNode>> iter = objectNode.getFields();
            String pathPrefix = currentPath.isEmpty() ? "" : currentPath + ".";

            while (iter.hasNext()) {
                Map.Entry<String, JsonNode> entry = iter.next();
                // Customization here
                if (entry.getKey().equals("items")) {
                    ArrayNode arrayNode = (ArrayNode) entry.getValue();
                    for (int i = 0; i < arrayNode.size(); i++) {
                        addKeys(currentPath + entry.getKey() + "[" + i + "]", arrayNode.get(i).get("id"), map);
                    }
                } else {
                    addKeys(pathPrefix + entry.getKey(), entry.getValue(), map);
                }
            }
        } else if (jsonNode.isArray()) {
            ArrayNode arrayNode = (ArrayNode) jsonNode;
            for (int i = 0; i < arrayNode.size(); i++) {
                addKeys(currentPath + "[" + i + "]", arrayNode.get(i), map);
            }
        } else if (jsonNode.isValueNode()) {
            ValueNode valueNode = (ValueNode) jsonNode;
            map.put(currentPath, valueNode.asText());
        }
    }
}

尝试了解所需的格式,然后研究上面的代码。 它应该给你答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM