Search code examples
javaxmljaxp

How to let Java.xml.Transformer output a xml without any useless space or line break?


My Code Now:

import org.w3c.dom.Node;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

private String getStringByJAXP(Node input) {
        StreamResult xmlOutput;
        try {
            xmlOutput = new StreamResult(new StringWriter());
            transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.transform(new DOMSource(input), xmlOutput);
        } catch (TransformerException e) {
            throw new IllegalArgumentException();
        }
        return xmlOutput.getWriter().toString();
    }

Output:

<aaa>
    <a>text a</a>
    <b>
        <c>text c</c>
    </b>
    <f>
        <g><h a="xxx"/></g>
    </f>
</aaa>

But I want to output as follows:

<aaa><a>text a</a><b><c>text c</c></b><f><g><h a="xxx" /></g></f></aaa>

Notice that I can't do that task by some simple string replaces, because the space in <a>text a</a> shouldn't be replaced(<a>texta</a> is total different from <a>text a</a>).

EDIT:

OutputKeys.INDENT, "no" not works. Updated code:

private String getStringByJAXP(Node input) {
    StreamResult xmlOutput;
    try {
        xmlOutput = new StreamResult(new StringWriter());
        transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "no");
        transformer.transform(new DOMSource(input), xmlOutput);
    } catch (TransformerException e) {
        throw new IllegalArgumentException();
    }
    return xmlOutput.getWriter().toString();
}

Solution

  • I had a similar case once. I tried transformer.setOutputProperty(OutputKeys.INDENT,"no"); first, but this did not work. The problem was that my original node had additional "new line" text nodes.

    The answer to Strip whitespace and newlines from XML in Java fixed it for me. Basically, you just remove the unnecessary text nodes before you transform the parent node.

    I ended up using this:

    public static void trimWhitespace(Node node)
    {
        NodeList children = node.getChildNodes();
        for(int i = 0; i < children.getLength(); ++i) {
            Node child = children.item(i);
            if(child.getNodeType() == Node.TEXT_NODE) {
                child.setTextContent(child.getTextContent().trim());
            }
            trimWhitespace(child);
        }
    }