Java tutorial
//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); } }