【问题标题】:Parsing JSON file using Jackson in Java and writing information one by one to an single Object在Java中使用Jackson解析JSON文件并将信息一一写入单个对象
【发布时间】:2021-04-15 16:58:41
【问题描述】:

我正在尝试将大型 JSON/JSON-LD 文件转换为 XML。 JSON 文件将包含一个事件列表(并非所有事件都相同,每个事件可能有不同的信息/数据)。我想一一阅读事件并将信息存储在单个对象中(而不是为每个事件使用不同的对象)。我想以父母和孩子的形式存储它。一旦我读到一个事件,我想将其转换为 JSON,然后转到下一个。

我正在研究 JACKSON,似乎它适合这个。但是,我正在研究这个特定的课程TokenBuffer,它实际上是在做同样的事情。它逐行读取 JSON 文件,然后尝试根据它做出各种决定来查看传入元素是数组还是对象。

我想确认是否可以直接使用这个类来传递我的 JsonFile 并获取将存储在 JsonWriteContext 中的父子关系,稍后我可以将其转换为 XML。

基本上,我的示例文件将在 JSON 中包含许多事件,我想一一读取这些事件,然后在单个对象(例如 HashMap)中获取元素信息及其父子关系。

【问题讨论】:

    标签: java json jackson json-ld jackson2


    【解决方案1】:

    在尝试了以下一些事情之后,我的代码将包含来自 Json 的 Parent 和 Child 元素:

    @Getter
    @Setter
    @NoArgsConstructor
    public class JsonContext {
        private JsonContext parent;
        private String key;
        private String value;
        private int childCount;
        private Map<String, List<JsonContext>> children = new HashMap<String, List<JsonContext>>();
    
        // Constructor for Children Object
        JsonContext(String key, String value) {
            this.key = key;
            this.value = value;
        }
    
        // Constructor for Parent Object
        JsonContext(JsonContext parent, String key, String value) {
            this(key, value);
            this.parent = parent;
        }
    
        // Add child based on incoming element
        public JsonContext addChild(JsonContext context) {
            List<JsonContext> childValues = children.get(context.getKey());
            if (childValues == null) {
                childValues = new ArrayList<JsonContext>();
            }
            childValues.add(context);
            children.put(context.key, childValues);
            childCount++;
            return context;
        }
    
        // Get the parent and their subsequent children (test purpose only)
        @Override
        public String toString() {
            String s = key + children.entrySet().stream().map(e -> e.getKey() + " -- " + String.join(", ", e.getValue().stream().map(v -> v.toString())
                                .collect(Collectors.toList()))).collect(Collectors.toList());
    
            if (value.length() > 0) {
                final String chars = value.toString().trim();
                if (chars.length() > 0) {
                    s = s + " = " + chars;
                }
            }
            return s;
        }
    
    }
    

    上面是存储信息的上下文文件。下面是 JSON 解析器文件。

    import java.io.File;
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.Arrays;
    
    import com.converter.xml2jsonld.test.JSONParser;
    import com.fasterxml.jackson.core.JsonFactory;
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonToken;
    
    public class JsonEventsParser {
    
        private JsonContext context = null;
        private final String[] eventTypes = new String[] { "event1", "event2", "event3", "event4",
                            "event5" };
    
        public void jsonFileIterator() throws URISyntaxException, JsonParseException, IOException {
            // Get the JSON Factory and parser Object
            JsonFactory jsonFactory = new JsonFactory();
            JsonParser jsonParser = jsonFactory.createParser(new File(JSONParser.class.getClassLoader().getResource("inputJsonFile.json").toURI()));
            JsonToken current = jsonParser.nextToken();
    
            // Check the first element is Object
            if (current != JsonToken.START_OBJECT) {
                throw new IllegalStateException("Expected content to be an array");
            }
    
            // Call the method to loop until the end of the events file
            FileNavigator(jsonParser);
        }
    
        private void FileNavigator(JsonParser jsonParser) throws IOException {
    
            JsonToken current = jsonParser.getCurrentToken();
    
            // Loop until the end of the EPCIS events file
            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
    
                final JsonToken token = jsonParser.nextToken();
                final String name = jsonParser.getCurrentName();
    
                // Handling the fields with direct key value pairs
                if ((token == JsonToken.FIELD_NAME || token == JsonToken.VALUE_STRING)) {
                    writeFieldName(jsonParser, token);
                }
    
                // Handling the Object
                if (token == JsonToken.START_OBJECT) {
                    writeObjectFields(jsonParser, token);
                }
    
                // Handling the Array
                if (token == JsonToken.START_ARRAY) {
                    writeArrayFields(jsonParser, token);
                }
    
                if (context != null) {
                    if (context.getParent() != null) {
                        context = context.getParent();
                    }
                }
            }
            System.out.println(context.getChildren().toString());
        }
    
        // Method to obtain the STRING field and write into Context
        private void writeFieldName(JsonParser jsonParser, JsonToken token) throws IOException {
            final String key = jsonParser.getCurrentName();
            final String value = jsonParser.getValueAsString();
    
            // Check for the eventType
            if (context == null && Arrays.asList(eventTypes).contains(value)) {
                context = new JsonContext(key, value);
            } else if (context != null) {
                context = context.addChild(new JsonContext(context, key, value));
            }
    
        }
    
        // Method to obtain the OBJECT and write its children into Context
        private void writeObjectFields(JsonParser jsonParser, JsonToken token) throws IOException {
    
            final String objectParent = jsonParser.getCurrentName() == null ? context.getParent().getKey() : jsonParser.getCurrentName();
            // Add the name of the OBJECT
            if (context == null) {
                context = new JsonContext(jsonParser.getCurrentName(), "Object");
            } else if (context != null) {
                context = context.addChild(new JsonContext(context, objectParent, "Object"));
            }
    
            token = jsonParser.nextToken();
    
            // Loop through all elements within OBJECT and add them to its parent
            while (token != JsonToken.END_OBJECT) {
                final String key = jsonParser.getCurrentName();
                token = jsonParser.nextToken();
                // Check for incoming tokens within array and process accordingly
                switch (token) {
                case START_ARRAY:
                    writeArrayFields(jsonParser, token);
                    break;
                case START_OBJECT:
                    writeObjectFields(jsonParser, token);
                    break;
                default:
                    final String value = jsonParser.getText();
                    context = context.addChild(new JsonContext(context, key, value));
                    break;
                // throw new RuntimeException("Object : Elements does not match the type
                // (Method: writeObjectFields)");
                }
    
                context = context.getParent();
                token = jsonParser.nextToken();
            }
        }
    
        // Method to Obtain the ARRAY and write its children into Context
        private void writeArrayFields(JsonParser jsonParser, JsonToken token) throws IOException {
    
            final String arrayField = jsonParser.getCurrentName();
            // Add the name of the ARRAY
            if (context == null) {
                context = new JsonContext(arrayField, "Array");
            } else if (context != null) {
                context = context.addChild(new JsonContext(context, arrayField, "Array"));
            }
    
            token = jsonParser.nextToken();
    
            // Loop through all ARRAY elements
            while (token != JsonToken.END_ARRAY) {
    
                switch (token) {
                case START_OBJECT:
                    writeObjectFields(jsonParser, token);
                    break;
                case VALUE_STRING:
                    context = context.addChild(new JsonContext(context, arrayField, jsonParser.getText()));
                    break;
                case START_ARRAY:
                    writeArrayFields(jsonParser, token);
                    break;
                default:
                    throw new RuntimeException("Array : Elements does not match the type (Method: writeArrayFields)");
                }
    
                context = context.getParent();
                token = jsonParser.nextToken();
            }
        }
    }
    

    【讨论】:

    • 使用 JACKSON2 有更简单的方法来操作 JSON。为什么选择JSONParsor?您有什么具体要求吗??
    • 唯一的要求是我不想将完整的 JSON 文件加载到内存中。我想一个一个地读取 JSON 中的事件,因此一次只有一个事件存在于内存中,我可以处理并以类似的方式继续下一个事件,直到文件结束。由于事件可能很复杂并且可能属于不同类型,因此我使用单个上下文而不是多个类,每个类都用于不同的事件。您能否指导我使用其他更简单有效的方法?
    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    相关资源
    最近更新 更多