package nl.hsac.fitnesse.fixture.util;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * Formats XML.
 */
public class XMLFormatter implements Formatter {
    /**
     * Creates formatted version of the supplied XML.
     * @param xml XML to format.
     * @return formatted version.
     */
    public String format(String xml) {
        try {
            boolean keepDeclaration = xml.startsWith("<?xml");

            Source xmlInput = new StreamSource(new StringReader(xml));
            StreamResult xmlOutput = new StreamResult(new StringWriter());
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            if (keepDeclaration) {
                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
            }
            transformer.transform(xmlInput, xmlOutput);
            return xmlOutput.getWriter().toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

@@ -347,16 +347,80 @@
 gWriter;
+%0Aimport java.util.regex.Matcher;%0Aimport java.util.regex.Pattern;
 %0A%0A/**%0A *
@@ -486,16 +486,229 @@
 atter %7B%0A
+    public static final Pattern DECL_PATTERN = Pattern.compile(%22%5E%3C%5C%5C?xml%5C%5Cs.*?%5C%5C?%3E%22, Pattern.DOTALL);%0A    public static final Pattern ELEMENT_CONTENT_PATTERN = Pattern.compile(%22%3E%5C%5Cs*(.*?)%5C%5Cs*%3C%22, Pattern.DOTALL);%0A%0A
     /**%0A
@@ -931,30 +931,42 @@
 n = 
-xml.startsWith(%22%3C?xml%22
+DECL_PATTERN.matcher(xml).matches(
 );%0A%0A
@@ -1753,16 +1753,16 @@
 ion(e);%0A
-
         
@@ -1768,11 +1768,965 @@
  %7D%0A    %7D
+%0A%0A    /**%0A     * Removes both XML declaration and trims all elements.%0A     * @param xml XML to trim.%0A     * @return trimmed version.%0A     */%0A    public static String trim(String xml) %7B%0A        String content = removeDeclaration(xml);%0A        return trimElements(content);%0A    %7D%0A%0A    /**%0A     * Removes XML declaration (if present).%0A     * @param xml XML to remove declaration from.%0A     * @return XML without declaration.%0A     */%0A    public static String removeDeclaration(String xml) %7B%0A        Matcher matcher = DECL_PATTERN.matcher(xml);%0A        return matcher.replaceFirst(%22%22);%0A    %7D%0A%0A    /**%0A     * Removes whitespace before and after each elements (and the entire document).%0A     * @param xml XML to trim.%0A     * @return trimmed version.%0A     */%0A    public static String trimElements(String xml) %7B%0A        String result = xml.trim();%0A        Matcher matcher = ELEMENT_CONTENT_PATTERN.matcher(result);%0A        return matcher.replaceAll(%22%3E$1%3C%22);%0A    %7D
 %0A%7D%0A

Add methods to remove whitespace and declarations from an XML string