Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;
//License from project: Open Source License 

import java.io.IOException;
import java.io.StringReader;

import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import com.google.gson.JsonPrimitive;

public class Main {
    private static final String EQ = "\"";
    private static final String EMPTY = "";
    private static final String ATTR_TEXT = "#text";
    static List<Object> ADDED_BY_VALUE = new ArrayList<Object>();
    static Map<String, JsonElement> REORGANIZED = new HashMap<String, JsonElement>();

    /**
     * Transform XML to JSON
     *
     * @param xml
     * @return
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public static String toJson(String xml) throws ParserConfigurationException, SAXException, IOException {
        JsonObject rootJson = new JsonObject();
        DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = dBuilder.parse(new InputSource(new StringReader(xml)));
        if (doc.hasChildNodes()) {
            traverseNode(doc, rootJson, null);
        }
        Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
        String json = gson.toJson(rootJson);

        return json;
    }

    private static void traverseNode(Node parentNode, JsonObject parentJson, JsonObject upperJson) {
        NodeList childList = parentNode.getChildNodes();
        for (int i = 0; i < childList.getLength(); i++) {
            JsonObject childJson = new JsonObject();
            Node childNode = childList.item(i);

            if (childNode.getNodeType() == Node.TEXT_NODE) {
                if (childNode.getNodeValue().trim().length() != 0) {
                    // non empty text node reached, so add to the parent
                    processTextNode(parentNode, upperJson, childJson, childNode);
                }
            } else if (childNode.getNodeType() == Node.ELEMENT_NODE) {

                if (childNode.hasAttributes()) {
                    // attributes exist, so go thru them
                    traverseAttributes(childJson, childNode);
                }

                if (childNode.hasChildNodes()) {
                    // child nodes exist, so go into them
                    traverseNode(childNode, childJson, parentJson);
                }

                if (childNode.getNodeType() != Node.TEXT_NODE) {
                    // non text node element
                    if (ADDED_BY_VALUE.contains(childNode)) {
                        // already added as a value
                        if (parentJson.has(childNode.getNodeName())) {
                            // there is already such an element as expected
                            JsonElement existing = parentJson.get(childNode.getNodeName());
                            if (existing instanceof JsonPrimitive) {
                                // it is a primitive as expected
                                Iterator attrs = childJson.entrySet().iterator();
                                if (attrs.hasNext()) {
                                    // there are attributes, so reorganize the element to include the attributes and the
                                    // value as property - #text
                                    reorganizeForAttributes(parentJson, childNode, existing, attrs);
                                }
                            } else if (existing instanceof JsonArray) {
                                // already added and reorganized as an array, so take the last element of this type and
                                // add the attributes
                                Iterator attrs = childJson.entrySet().iterator();
                                if (attrs.hasNext()) {
                                    reorganizeAddAttributes(childNode, attrs);
                                }
                            } else if (existing instanceof JsonObject) {
                                System.err.println("ERROR: found object, but expected primitive or array");
                            }
                        } else {
                            System.err.println("ERROR: expected element, but it does not exist");
                        }
                        // remove it from the list
                        ADDED_BY_VALUE.remove(childNode);
                    } else {
                        if (parentJson.has(childNode.getNodeName())) {
                            // parent already has such an element
                            JsonElement existing = parentJson.get(childNode.getNodeName());
                            if (existing instanceof JsonArray) {
                                // and it is already an array, so just add the child to the array
                                ((JsonArray) existing).add(childJson);
                            } else if (existing instanceof JsonObject) {
                                // and it not an array, so reorganize the element
                                reorganizeElement(parentNode, parentJson, childJson, childNode, existing);
                            }
                        } else {
                            // no such an element yet, so add it to the parent
                            parentJson.add(childNode.getNodeName(), childJson);
                        }
                    }
                }
            } else if (childNode.getNodeType() == Node.CDATA_SECTION_NODE) {
                // processTextNode(parentNode, upperJson, childJson, childNode);
                String base64 = Base64.getEncoder().encodeToString(childNode.getNodeValue().getBytes());
                parentJson.addProperty(childNode.getNodeName(), base64);
            } else {
                System.err.println("ERROR: unsupported node type: " + childNode.getNodeType());
            }
        }
    }

    private static void processTextNode(Node parentNode, JsonObject upperJson, JsonObject childJson,
            Node childNode) {
        if (upperJson.has(parentNode.getNodeName())) {
            // upper already has such an element
            JsonElement existing = upperJson.get(parentNode.getNodeName());
            if (existing instanceof JsonArray) {
                // adding to the already reorganized array
                ((JsonArray) existing).add(new JsonPrimitive(childNode.getNodeValue()));
                REORGANIZED.put(parentNode.hashCode() + EMPTY, childJson);
            } else if (existing instanceof JsonObject) {
                // found it as an object, so reorganize it
                reorganizeObjectToArray(parentNode, upperJson, childJson, childNode, existing);
            } else {
                // found as a primitive, so reorganize it
                reorganizePrimitiveToArray(parentNode, upperJson, childJson, childNode, existing);
            }
        } else {
            // no such a node exists yet, so add it as a property to the upper element
            upperJson.addProperty(parentNode.getNodeName(), childNode.getNodeValue());
        }
        // add the parent node to the added as a value list
        ADDED_BY_VALUE.add(parentNode);
    }

    private static void traverseAttributes(JsonObject childJson, Node childNode) {
        NamedNodeMap attrNodeMap = childNode.getAttributes();
        for (int j = 0; j < attrNodeMap.getLength(); j++) {
            Node attrNode = attrNodeMap.item(j);
            childJson.addProperty("-" + attrNode.getNodeName(), attrNode.getNodeValue());
        }
    }

    private static void reorganizeForAttributes(JsonObject parentJson, Node childNode, JsonElement existing,
            Iterator attrs) {
        parentJson.remove(childNode.getNodeName());
        JsonObject objectJson = new JsonObject();
        objectJson.addProperty(ATTR_TEXT, ((JsonPrimitive) existing).getAsString());
        while (attrs.hasNext()) {
            Entry entry = (Entry) attrs.next();
            objectJson.addProperty(entry.getKey().toString(), entry.getValue().toString().replace(EQ, EMPTY));
        }
        parentJson.add(childNode.getNodeName(), objectJson);
    }

    private static void reorganizeAddAttributes(Node childNode, Iterator attrs) {
        JsonElement reorganizedJson = REORGANIZED.get(childNode.hashCode() + EMPTY);
        if (reorganizedJson instanceof JsonObject) {
            JsonObject objectJson = (JsonObject) reorganizedJson;
            while (attrs.hasNext()) {
                Entry entry = (Entry) attrs.next();
                objectJson.addProperty(entry.getKey().toString(), entry.getValue().toString().replace(EQ, EMPTY));
            }
        } else {
            System.err.println("ERROR: expected object, found element or null");
        }
        REORGANIZED.remove(childNode.hashCode() + EMPTY);
    }

    private static void reorganizeElement(Node parentNode, JsonObject parentJson, JsonObject childJson,
            Node childNode, JsonElement existing) {
        parentJson.remove(childNode.getNodeName());
        JsonArray arrayJson = new JsonArray();
        arrayJson.add(existing);
        arrayJson.add(childJson);
        parentJson.add(childNode.getNodeName(), arrayJson);
    }

    private static void reorganizeObjectToArray(Node parentNode, JsonObject upperJson, JsonObject childJson,
            Node childNode, JsonElement existing) {
        upperJson.remove(parentNode.getNodeName());
        JsonArray arrayJson = new JsonArray();
        arrayJson.add(existing);
        childJson.addProperty(childNode.getNodeName(), childNode.getNodeValue());
        arrayJson.add(childJson);
        upperJson.add(parentNode.getNodeName(), arrayJson);
        REORGANIZED.put(parentNode.hashCode() + EMPTY, childJson);
    }

    private static void reorganizePrimitiveToArray(Node parentNode, JsonObject upperJson, JsonObject childJson,
            Node childNode, JsonElement existing) {
        upperJson.remove(parentNode.getNodeName());
        JsonArray arrayJson = new JsonArray();
        arrayJson.add(existing);
        arrayJson.add(new JsonPrimitive(childNode.getNodeValue()));
        upperJson.add(parentNode.getNodeName(), arrayJson);
        REORGANIZED.put(parentNode.hashCode() + EMPTY, childJson);
    }
}