Получить структуру линии из многослойного ObjectNode

1

У меня есть ObjectNode как входной параметр, и я не знаю точной структуры этого узла. Я имею в виду, что он может иметь любое количество слоев внутри, от очень простого массива NameValuePair<String,String> до сложной структуры, такой как HashMap<String,Object>. Как я могу разобрать его на простую плоскую структуру, например массив NameValuePair<String,String>? Я сделал это раньше для ObjectNodes с известной структурой, но теперь я понятия не имею.

Я ценю любую помощь и любые идеи.

Добавление сведений: например, если я знаю, что внутри ObjectNode я всегда найду только HashMap<String,String>, и все, что я могу сделать:

ObjectNode parametersNode = (ObjectNode) request.get("parameters");
        Iterator fieldNames = parametersNode.getFieldNames();
        HashMap<String,String> oldParams = new HashMap<String,String>();

        while (fieldNames.hasNext()) {
            String name = (String) fieldNames.next();
            oldParams.put(name, parametersNode.get(name).asText());
        }

Но что, если структура этого ObjectNode является черным ящиком? Я не знаю, есть карта или массив, или куча карт внутри Карты. Это может быть из разных источников, и я не знаю, какую структуру я получу в любой момент. может быть:

{
"name":"value",
"name1":"value1"
}

или

{
"name":"value",
"arg1": [
         "name1":"value1",
         "name1":"value1"
        ]
}

или

{
"name":"value",
"arg1": [
         {"name1":"value1"},
         {"name1":"value1"}
        ]
}

или более сложной структуры. И у меня нет информации заранее, что я получаю. Как преобразовать такой черный ящик ObjectNode в плоский массив пар имя-значение? Есть ли универсальный алгоритм?

В конце я должен получить простую структуру, как это, несмотря на сложность исходной структуры:

{
  "name":"value",
  "name1":"value1",
  "name2":"value2"
}
  • 0
    Пожалуйста, добавьте больше деталей, немного кода
  • 0
    @ Кофе Я отредактировал свое сообщение, теперь оно имеет больше смысла?
Показать ещё 4 комментария
Теги:
jackson
parsing
gson

1 ответ

0
Лучший ответ

Поскольку у меня нет ответов, я сделал это сам. Для тех, кто столкнутся с той же проблемой, я размещаю ее здесь. Это без какой-либо рекурсии, и я использовал HashMap, где я не должен, но это как доказательство концепции и предназначено для рефакторинга. Обратите внимание, что он был протестирован как веб-сервис на Switchyard через Postman, поэтому никакого основного метода.

public ArrayList<HashMap<String, String>> convertToFlatFormat(
            JsonNode request) {
        Stack<Pair> stack = new Stack<Pair>();
        ArrayList<HashMap<String, String>> parametersList = new ArrayList<HashMap<String, String>>();
        stack.push(new Pair("", request));
        HashMap<String, Integer> counts = new HashMap<String, Integer>();
        while (!stack.isEmpty()) {
            Pair higherNodePair = stack.pop();
            String nodeName = higherNodePair.name;
            JsonNode higherNode = (JsonNode) higherNodePair.object;
            String newNamePrefix = "";
            if (higherNode.isArray()) {
                ArrayNode higherArrayNode = (ArrayNode) higherNode;
                for (int i = 0; i < higherNode.size(); i++) {
                    JsonNode node = higherArrayNode.get(i);
                    String key = new Integer(i).toString();
                    if (node.isObject()) {
                        if (nodeName.equals("")) {
                            stack.push(new Pair(newNamePrefix, node));
                        } else {
                            stack.push(new Pair(nodeName + "_" + newNamePrefix
                                    , node));
                        }
                    } else if (node.isArray()) {
                        if (nodeName.equals("")) {
                            stack.push(new Pair(newNamePrefix, node));
                        } else {
                            stack.push(new Pair(nodeName + "_" + newNamePrefix
                                    , node));
                        }
                    } else if (node.isValueNode()) {
                        ValueNode valueNode = (ValueNode) node;
                        String value = valueNode.getTextValue();
                        HashMap<String, String> pair = null;
                        if (nodeName.equals("")) {
                            pair = new HashMap<String, String>();
                            pair.put(newNamePrefix + key, value);
                        } else {
                            pair = new HashMap<String, String>();
                            pair.put(nodeName + "_" + newNamePrefix + key,
                                    value);
                        }
                        parametersList.add(pair);
                    }
                }

            } else {
                Iterator<String> iterate = higherNode.getFieldNames();
                while (iterate.hasNext()) {
                    String key = iterate.next();
                    JsonNode node = higherNode.get(key);
                    if (node.isObject()) {
                        if (nodeName.equals("")) {
                            stack.push(new Pair(newNamePrefix + key, node));
                        } else {
                            stack.push(new Pair(nodeName + "_" + newNamePrefix
                                    + key, node));
                        }
                    } else if (node.isArray()) {
                        if (nodeName.equals("")) {
                            stack.push(new Pair(newNamePrefix + key, node));
                        } else {
                            stack.push(new Pair(nodeName + "_" + newNamePrefix
                                    + key, node));
                        }
                    } else if (node.isValueNode()) {
                        ValueNode valueNode = (ValueNode) node;
                        String value = valueNode.getTextValue();
                        HashMap<String, String> pair = null;
                        if (nodeName.equals("")) {
                            pair = new HashMap<String, String>();
                            pair.put(newNamePrefix + key, value);
                        } else {
                            pair = new HashMap<String, String>();
                            pair.put(nodeName + "_" + newNamePrefix + key,
                                    value);
                        }
                        parametersList.add(pair);
                    }
                }
            }
        }
        return parametersList;
    }

    private class Pair {
        public String name;
        public Object object;

        public Pair(String name, Object object) {
            this.name = name;
            this.object = object;
        }
    }

Вход:

{
 "name1":"value1",
 "name2":"value2",
  "name3":[
         {
          "ComponentId":"qwer",
          "InstanceId":"amba"
         },
         {
          "ComponentId":"qwer",
          "InstanceId":"coramba"
         },
         {
          "ComponentId":"dsa",
          "InstanceId":"badar"
         },
         {
          "ComponentId":"dsa",
          "InstanceId":"fdarr"
         },
         {
          "ComponentId":"dsa",
          "InstanceId":"sdddd"
         }
         ]
}

Выход:

[
    {
        "name1": "value1"
    },
    {
        "name2": "value2"
    },
    {
        "name3__dsa_1_ComponentId": "dsa"
    },
    {
        "name3__dsa_1_InstanceId": "sdddd"
    },
    {
        "name3__dsa_2_ComponentId": "dsa"
    },
    {
        "name3__dsa_2_InstanceId": "fdarr"
    },
    {
        "name3__dsa_3_ComponentId": "dsa"
    },
    {
        "name3__dsa_3_InstanceId": "badar"
    },
    {
        "name3__qwer_1_ComponentId": "qwer"
    },
    {
        "name3__qwer_1_InstanceId": "coramba"
    },
    {
        "name3__qwer_2_ComponentId": "qwer"
    },
    {
        "name3__qwer_2_InstanceId": "amba"
    }
]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню