class XmlTool {

    public static String normalize(Object xml) throws IOException, TransformerException, ParserConfigurationException,
            SAXException, XPathExpressionException {

        if (xml == null) {
            return null;
        }

        Source xsltSource = new StreamSource(new StringReader(readResourceFile("normalize-namespaces.xsl")));

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        DocumentBuilder db = dbFactory.newDocumentBuilder();
        InputSource source = new InputSource(new StringReader(String.valueOf(xml)));
        Document doc = db.parse(source);

        // Start of code to remove whitespace outside of tags
        XPath xPath = XPathFactory.newInstance().newXPath();
        NodeList nodeList = (NodeList) xPath.evaluate("//text()[normalize-space()='']", doc, XPathConstants.NODESET);

        for (int i = 0; i < nodeList.getLength(); ++i) {
            Node node = nodeList.item(i);
            node.getParentNode().removeChild(node);
        }
        // End of code to remove whitespace outside of tags

        // the factory pattern supports different XSLT processors
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        Transformer transformer = transformerFactory.newTransformer(xsltSource);

        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        return writer.toString().trim();
    }

    private  XmlTool();

}