Извлеките определенные значения, заключенные в кавычки, с помощью java

Я читаю REST API в формате JSON. При чтении JSON я не могу извлечь листья с помощью JSONPath. Итак, что я хотел бы сделать, это запустить строку JSON с Java и получить нужные мне значения, они всегда в одном и том же порядке. Это строка JSON, из которой мне нужно извлечь значения:

{
"10516": {
    "estimated": {
        "value": 10.0,
        "text": "10.0"
    },
    "completed": {
        "value": 7.5,
        "text": "7.5"
    }
},
"10244": {
    "estimated": {
        "value": 15.5,
        "text": "15.5"
    },
    "completed": {
        "value": 7.5,
        "text": "7.5"
    }
},
"10182": {
    "estimated": {
        "value": 12.0,
        "text": "12.0"
    },
    "completed": {
        "value": 10.0,
        "text": "10.0"
    }
},
"10391": {
    "estimated": {
        "value": 16.0,
        "text": "16.0"
    },
    "completed": {
        "value": 3.0,
        "text": "3.0"
    }
},
"10183": {
    "estimated": {
        "value": 12.0,
        "text": "12.0"
    },
    "completed": {
        "value": 7.0,
        "text": "7.0"
    }
},
"10123": {
    "estimated": {
        "value": 11.5,
        "text": "11.5"
    },
    "completed": {
        "value": 5.5,
        "text": "5.5"
    }
},
"10447": {
    "estimated": {
        "value": 7.0,
        "text": "7.0"
    },
    "completed": {
        "value": 3.0,
        "text": "3.0"
    }
}}

Как видите, идентификатор 10516 имеет estimated и completed, я хотел бы извлечь эти значения для каждого идентификатора. Таким образом, вывод должен выглядеть следующим образом:

ID    | ESTIMATED  |  COMPLETED
10516 | 10.0       |  7.5
10244 | 15.5       |  7.5
10182 | 12.0       |  10.0

и так далее..

важно, чтобы для каждого идентификатора значения находились в одной строке, потому что мне нужно загрузить их в мою базу данных PostgreSQL и соединить эти данные с другими данными в идентификаторе.

Моя идея состоит в том, чтобы подсчитать значения, заключенные в кавычки, и получить 1-е, 5-е, 9-е, 10-е, 14-е и 18-е значения и так далее. потому что строка JSON всегда в одном и том же порядке, я думаю, это можно сделать так.

пожалуйста, помогите и имейте в виду, что у меня нет никакого опыта в Java, и реализация будет выполнена в Talend Open Studio. также см. мой другой вопрос, который поднял этот вопрос, потому что JSONPath не может мне помочь: Файл JSON с JSONpath


person StackedOverflow    schedule 13.10.2016    source источник
comment
Если вы хотите использовать Java, используйте правильный анализатор JSON. Попытка проанализировать это как открытый текст доставит вам больше проблем, чем пользы.   -  person RealSkeptic    schedule 13.10.2016
comment
спасибо за ответ @RealSkeptic, но какой анализатор JSON поможет мне извлечь листья (10516,10244 и т. д.)? потому что с JSONPath кажется, что вы не можете извлекать значения без меток... при извлечении значений из estimated и completed у меня нет проблем, потому что у них есть метка, к которой я могу обратиться,   -  person StackedOverflow    schedule 13.10.2016
comment
Любой парсер JSON позволит вам это сделать. Только не настаивайте на использовании XPath для этого. Просто проанализируйте объект и повторите ключи. См. Как анализировать JSON в Java.   -  person RealSkeptic    schedule 13.10.2016


Ответы (1)


какой парсер JSON поможет мне извлечь листья (10516,10244 и т. д.)?

Примеры с Джексоном (com.fasterxml.jackson.core:jackson-databind:2.0.6):

Быстрый и грязный подход:

    String json = "{\n" +
            "\"10516\": {\"estimated\": {\"value\": 10.0,\"text\": \"10.0\"},\"completed\": {\"value\": 7.5,\"text\": \"7.5\"}},\n" +
            "\"10244\": {\"estimated\": {\"value\": 15.5,\"text\": \"15.5\"},\"completed\": {\"value\": 7.5,\"text\": \"7.5\"}},\n" +
            "\"10182\": {\"estimated\": {\"value\": 12.0,\"text\": \"12.0\"},\"completed\": {\"value\": 10.0,\"text\": \"10.0\"}}\n" +
            "}";

    ObjectMapper mapper = new ObjectMapper();
    TypeReference<Map> typeRef = new TypeReference<Map>(){};
    try {
        Map<String, Object> map = mapper.readValue(json, typeRef);
        System.out.println(map);
    } catch (IOException e) {
        // log error
    }

Выход:

{10516={estimated={value=10.0, text=10.0}, completed={value=7.5, text=7.5}}, 10244={estimated={value=15.5, text=15.5}, completed={value=7.5, text=7.5}}, 10182={estimated={value=12.0, text=12.0}, completed={value=10.0, text=10.0}}}

Таким образом вы можете анализировать любую строку JSON. Конечно, вы можете получить доступ ко всем полям JSON, если вы приводите к соответствующему типу:

        Map item = (Map) map.get("10182");
        System.out.println(item);

        Map estimated = (Map) item.get("estimated");
        Double value = (Double) estimated.get("value");
        System.out.println(value);

        String text = (String) estimated.get("text");
        double newValue = value + 10;
        System.out.println("old text: "+text+", new value: "+newValue);

Выход:

{estimated={value=12.0, text=12.0}, completed={value=10.0, text=10.0}}
12.0
old text: 12.0, new value: 22.0

Более чистый и лучший подход

Конечно, лучшим подходом было бы определение некоторых классов моделей, таких как следующие:

class Model {
    ModelContent estimated;
        public ModelContent getEstimated() {return estimated;}
        public void setEstimated(ModelContent estimated) { this.estimated = estimated;}
    ModelContent completed;
        public ModelContent getCompleted() {return completed;}
        public void setCompleted(ModelContent completed) { this.completed = completed;}
    public Model() {}
}


class ModelContent {
    Double value;
        public Double getValue() {return value;}
        public void setValue(Double value) { this.value = value;}
    String text;
        public String getText() {return text;}
        public void setText(String text) {this.text = text;}
    public ModelContent() {}
}

И используйте их как тип значения для корневой карты:

    ObjectMapper mapper = new ObjectMapper();
    TypeReference<Map<String,Model>> typeRef = new TypeReference<Map<String,Model>>(){};
    try {
        Map<String, Model> map = mapper.readValue(json, typeRef);
        Model item = map.get("10182");
        ModelContent completed = item.getCompleted();
        Double completedValue = completed.getValue();
        System.out.println("value: "+completedValue);
    } catch (IOException e) {
        // log error
    }

Выход:

value: 10.0
person walen    schedule 13.10.2016