import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;

public class DOMCreatingExample {

	public static void main(String[] args) {

		Document document = null;

		// To create a DOM tree, we first need to instantiate the DocumentBuilderFactory and create a DocumentBuilder
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		try {
			DocumentBuilder builder = factory.newDocumentBuilder();

			// A new document can be created with the DocumentBuilder
			document = builder.newDocument();

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		}

		// Then we can start building the document, by creating elements, attributes and text contents etc.

		// an element "rootElement" is created
		Element root = document.createElement("rootElement");

		// "rootElement" is added to the document, it is the root element of the XML document
		document.appendChild(root);

		// let's create an element "childOfRootElement" and add it to the document
		Element childElement = document.createElement("childOfRootElement");
		root.appendChild(childElement);

		// "childOfRootElement" has an attribute "name" with a value "nameOfElement"
		childElement.setAttribute("name", "nameOfElement");

		// let's add some text content to "childOfRootElement"		
		childElement.appendChild(document.createTextNode("This is text."));

		// let's print the document
		processNodesRecursively(document);
	}

	private static void processNodesRecursively(Node node) {
		int parents = 0;

		if (node.getNodeType() == Node.ELEMENT_NODE) {
			// For each element node, print the element name
			// The indentation of the element name depends on the amount of its parents
			parents = countParents(node, 0);
			for (int i=1; i<parents; i++)
				System.out.print(" ");
			System.out.println("Element "+node.getNodeName()+":");

			// Print all the elements attributes
			NamedNodeMap attributes = node.getAttributes();
			if (attributes != null) {
				for (int j=0; j<attributes.getLength(); j++) {
					for (int k=0; k<parents; k++)
						System.out.print(" ");
					Node attribute = attributes.item(j);
					System.out.println("Attribute: "+attribute.getNodeName()+"="+attribute.getNodeValue());
				}
			}
		}

		// Then process the children elements recursively
		NodeList childNodes = node.getChildNodes();
		for (int i=0; i<childNodes.getLength(); i++) {
			Node child = childNodes.item(i);
			if (child.getNodeType() == Node.ELEMENT_NODE)
				processNodesRecursively(child);
			// if node is a text node, print it
			if (child.getNodeType() == Node.TEXT_NODE && child.getNodeValue().trim().length() > 0) {
				for (int l=0; l<parents; l++)
					System.out.print(" ");
				System.out.println("Text content: "+child.getNodeValue());
			}
		}
	}
	
	private static int countParents(Node node, int count) {
		// counts the parent nodes recursively
		if (node.getParentNode() != null)
			return countParents(node.getParentNode(), ++count);
		else
			return count;
	}
}
