Java tutorial
//package com.java2s; public class Main { /*** * Fast xml formatter without loading xml into a document or using a * serializer. * * @param content * @param lineBreaker * @param nodeSpacer * @return */ public static String prettyPrintNoDoc(String content, String lineBreaker, String nodeSpacer) { if (content == null || content.length() == 0) { return null; } else { StringBuilder prettyPrintBuilder = new StringBuilder(content.length() + 200); boolean inQuote = false; boolean inData = false; int nodeDepth = 0; char prevCh = 0; char lastMeaningfulChar = 0; for (int i = 0; i < content.length(); i++) { char ch = content.charAt(i); char nextCh = i < content.length() - 1 ? content.charAt(i + 1) : 0; if (inData) { // We are in <!-- or <!CDATA[[ block, find when to // exit it if ('>' == ch && prettyPrintBuilder.length() >= 2) { String lastTwoChar = prettyPrintBuilder.substring(prettyPrintBuilder.length() - 2); if ("--".equals(lastTwoChar) || "]]".equals(lastTwoChar)) { inData = false; lastMeaningfulChar = '>'; } } prettyPrintBuilder.append(ch); } else if (inQuote) { // in the quote, fine when to exit it if ('"' == ch) { inQuote = false; } prettyPrintBuilder.append(ch); } else { // Not in quote or data if (Character.isWhitespace(ch)) { if (!Character.isISOControl(prevCh) && !Character.isWhitespace(prevCh) && '>' != prevCh) { prettyPrintBuilder.append(' '); } ch = 0; } else if ('"' == ch) { inQuote = true; } else if ('<' == ch) { // We are at the start of a node if ('?' == nextCh) { // Start declaration node // move the nodeDepth to -1; nodeDepth = -1; } else if ('!' == nextCh) { // Start Data node inData = true; prettyPrintBuilder.append(lineBreaker); appendSpace(prettyPrintBuilder, nodeSpacer, nodeDepth + 1); } else if (i > 1) { // We are at the start of a regular // node or closing a regular node if ('>' == lastMeaningfulChar) { // A node just // finished // above prettyPrintBuilder.append(lineBreaker); if ('/' == nextCh) {// At closing of an node // section </ appendSpace(prettyPrintBuilder, nodeSpacer, nodeDepth); nodeDepth--; } else { // At starting of a node nodeDepth++; appendSpace(prettyPrintBuilder, nodeSpacer, nodeDepth); } } else if ('/' == nextCh) { // At closing of an node nodeDepth--; } } } else if ('/' == ch && '>' == nextCh) { // closing a node with /> nodeDepth--; } if (!Character.isISOControl(ch) && ch != 0) { prettyPrintBuilder.append(ch); if (!Character.isWhitespace(ch)) { lastMeaningfulChar = ch; } } } prevCh = ch; } return prettyPrintBuilder.toString(); } } private static void appendSpace(StringBuilder buffer, String spaceString, int numOfSpace) { for (int i = 0; i < numOfSpace; i++) { buffer.append(spaceString); } } }