Java tutorial
//package com.java2s; /** * This file is part of the au-xml-util package * * Copyright Trenton D. Adams <trenton daught d daught adams at gmail daught ca> * * au-xml-util is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * au-xml-util is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with au-xml-util. If not, see <http://www.gnu.org/licenses/>. * * See the COPYING file for more information. */ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.util.*; public class Main { static final int BUFFER_CAPACITY = 50000; /** * Converts a Map's keys and values to an XML document where the keys are * the elments, and the values are the textnodes (where value is String) or * subelements (where value is Map). In the case of a map entry with a List * as the value, it will create multiple elements, named by the key, and the * values will be the contents of the list, in list order. Note: use a * sorted list if you care about order. * <p/> * The following code, will produce the XML below it. For more examples, * you may look at the unit tests for MapTest * <pre> * final Map parameters; * final Map subElements; * final Map innerElements; * parameters = new HashMap(); * subElements = new HashMap(); * innerElements = new HashMap(); * parameters.put("element1", "value1"); * parameters.put("element2", "value2"); * parameters.put("element3", "value3"); * parameters.put("element4", subElements); * subElements.put("subelement1", "value1"); * subElements.put("subelement2", "value2"); * subElements.put("innermost", innerElements); * innerElements.put("innerelement1", "innervalue1"); * innerElements.put("innerelement2", "innervalue2"); * System.out.println(XMLUtil.mapToXML("root", parameters)); * </pre> * <pre> * <?xml version="1.0" encoding="UTF-8"?> * <root> * <element4> * <subelement2>value2</subelement2> * <subelement1>value1</subelement1> * <innermost> * <innerelement1>innervalue1</innerelement1> * <innerelement2>innervalue2</innerelement2> * </innermost> * </element4> * <element2>value2</element2> * <element3>value3</element3> * <element1>value1</element1> * </root> * </pre> * * @param rootElementName the name that you want the root element to have * @param elements the elements, whether a list of elements or a map * of key/value pairs * * @return the string representation of the XML document * * @throws TransformerException if an XSL transformation exception * occurs * @throws ParserConfigurationException if a JAXP configuration error * occurs */ public static String mapToXML(final String rootElementName, final Object elements) throws TransformerException, ParserConfigurationException { final Document mapDoc; final Element parent; mapDoc = createDocument(); parent = mapDoc.createElement(rootElementName); mapDoc.appendChild(parent); mapToNode(elements, parent, mapDoc, null); return documentToString(mapDoc); } /** * Generates a new document using the XML factory builder stuff. * * @return the new Document, never supposed to be null * * @throws ParserConfigurationException if a dom configuration error * occurs. */ public static Document createDocument() throws ParserConfigurationException { final DocumentBuilderFactory factory; final DocumentBuilder builder; final Document document; factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); document = builder.newDocument(); return document; } /** * Converts a map to XML, where parent is the parent element, and every * other element is of the form <key>value</key> or <listElementName>listvalue</listElementName> * for each list index. The list elements MUST be Strings if they are to * have text nodes. But, they may also be another Map with key/value * pairs. * <p/> * We assume that every key is an actual XML compatible element name; i.e. a * String object. The values will be XML encoded automatically. * * @param elements the elements, whether a list of elements or a map * of key/value pairs * @param parentElement the parent element to append the new child to * @param document the XML document to create new elements in * @param listElementName the name for the element, for every element in the * List * * @throws ParserConfigurationException if a configuration error occurs */ public static void mapToNode(final Object elements, final Element parentElement, final Document document, final String listElementName) throws ParserConfigurationException { Object value; if (elements instanceof Map) { final Map map = (Map) elements; final Iterator it = map.keySet().iterator(); Element tmp; while (it.hasNext()) { final String key = (String) it.next(); value = map.get(key); if (value instanceof Map) { tmp = document.createElement(key); mapToNode(value, tmp, document, null); parentElement.appendChild(tmp); } else if (value instanceof List) { mapToNode(value, parentElement, document, key); } else { tmp = document.createElement(key); if (value != null) { // null elements don't get in tmp.appendChild(document.createTextNode((String) value)); parentElement.appendChild(tmp); } } } } else if (elements instanceof List) { if (listElementName == null || "".equals(listElementName.trim())) { throw new IllegalArgumentException( "listElementName can never be null if a list is passed " + "in for elements"); } final List list = (List) elements; for (int index = 0; index < list.size(); index++) { final Object element = list.get(index); if (element instanceof String) { // text node final String text = (String) list.get(index); final Element tmp = document.createElement(listElementName); tmp.appendChild(document.createTextNode(text)); parentElement.appendChild(tmp); } else if (element instanceof Map) { // sub elements that have key/value pairs, or key/List pairs final Element tmp = document.createElement(listElementName); parentElement.appendChild(tmp); mapToNode(element, tmp, document, null); } else if (element instanceof List) { throw new IllegalArgumentException( "List not supported " + "inside of List, cannot determine element name"); } } } else { throw new IllegalArgumentException("unsupported class type for " + "mapToXML"); } } /** * Converts the given document to string format by passing it through a * transformer. * * @param node the node to convert to a java string. * * @return the XML string result * * @throws TransformerException if a transformation error occurs */ public static String documentToString(final Node node) throws TransformerException { final TransformerFactory transformerFactory; final Transformer transformer; final DOMSource source; final StreamResult result; final StringWriter writer; writer = new StringWriter(BUFFER_CAPACITY); transformerFactory = TransformerFactory.newInstance(); transformer = transformerFactory.newTransformer(); source = new DOMSource(node); result = new StreamResult(writer); transformer.transform(source, result); return writer.toString(); } }