import javax.xml.parsers.*;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import java.io.*;

/**
 * Parses and prints content of test.xml file. * The result should be identical
 * to the input except for the whitespace.
 */
public class DOMPrinter {
	public static void main(String[] args) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new File(args[0]));

			Node n = doc.getDocumentElement();
			System.out.println("<?xml version=\"1.0\"?>");
			if (n != null)
				System.out.println(printXML(n));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String printXML(Node node) throws IOException {
		StringWriter str = new StringWriter();

		printWithFormat(node, str, 0, false);
		str.flush();

		return str.toString();
	}

	private final static void printWithFormat(Node node, Writer wr, int n,
			boolean flush) throws IOException {
		switch (node.getNodeType()) {
		case Node.ELEMENT_NODE: {
			// Print opening tag
			wr.write(makeTabs(n) + "<" + node.getNodeName());
			if (flush)
				wr.flush();

			// Print attributes (if any)
			NamedNodeMap attrs = node.getAttributes();
			Node attr = null;
			if (attrs != null) {
				for (int i = 0; i < attrs.getLength(); i++) {
					attr = attrs.item(i);
					wr.write(" " + attr.getNodeName() + "=\""
							+ attr.getNodeValue() + "\"");
					if (flush)
						wr.flush();
				}
			}

			wr.write(">\n");
			if (flush)
				wr.flush();

			// recursively print children
			Node ch = node.getFirstChild();
			while (ch != null) {
				printWithFormat(ch, wr, n + 1, flush);
				if (flush)
					wr.flush();
				ch = (Node) ch.getNextSibling();
			}
			wr.write(makeTabs(n) + "</" + node.getNodeName() + ">\n");
			if (flush)
				wr.flush();
		}
			break;

		case Node.TEXT_NODE: {
			String text = node.getNodeValue().trim();
			// Make sure we don't print whitespace
			if (text.length() > 0)
				wr.write(makeTabs(n) + text + "\n");
			if (flush)
				wr.flush();
		}
			break;

		default:
			throw new IOException("Cannot print this type of element");
		}
	}

	private static final String makeTabs(int n) {
		StringBuffer result = new StringBuffer("");
		for (int i = 0; i < n; i++)
			result.append("\t");
		return result.toString();
	}
}