dnet-core/dnet-core-components/src/main/java/eu/dnetlib/miscutils/functional/xml/IndentXmlString.java

134 lines
3.7 KiB
Java

package eu.dnetlib.miscutils.functional.xml;
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import eu.dnetlib.miscutils.functional.UnaryFunction;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* The Class IndentXmlString.
*/
public class IndentXmlString implements UnaryFunction<String, String> {
/*
* (non-Javadoc)
*
* @see eu.dnetlib.miscutils.functional.UnaryFunction#evaluate(java.lang.Object)
*/
@Override
public String evaluate(final String unformattedXml) {
try {
return doIndent(unformattedXml);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Do indent.
*
* @param unformattedXml
* the unformatted xml
* @return the string
* @throws IOException
* Signals that an I/O exception has occurred.
*/
protected String doIndent(final String unformattedXml) throws IOException {
final Document document = parseXmlString(unformattedXml);
OutputFormat format = new OutputFormat(document);
format.setIndenting(true);
format.setIndent(2);
Writer out = new StringWriter();
XMLSerializer serializer = new XMLSerializer(out, format);
serializer.serialize(document);
return out.toString();
}
/**
* Parses the xml string.
*
* @param in
* the in
* @return the document
*/
protected Document parseXmlString(final String in) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(null);
InputSource is = new InputSource(new StringReader(in));
return db.parse(is);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String doIndent(final Document document) throws TransformerException, UnsupportedEncodingException {
final Transformer transformer = getTransformer();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
transformer.transform(new DOMSource(document), new StreamResult(out));
return out.toString("utf-8");
}
private Transformer getTransformer() throws TransformerConfigurationException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
return transformer;
}
private Document doIndentDocument(final Document document) throws TransformerException, UnsupportedEncodingException {
final Transformer transformer = getTransformer();
final DOMResult out = new DOMResult();
transformer.transform(new DOMSource(document), out);
return (Document) out.getNode();
}
/**
* Static helper Apply.
*
* @param xml
* the xml
* @return the indented xml string
*/
public static String apply(final String xml) {
return new IndentXmlString().evaluate(xml);
}
/**
* Static helper Apply.
*
* @param xml
* the xml
* @return the indented xml string
*/
public static Document apply(final Document xml) throws TransformerException, UnsupportedEncodingException {
return new IndentXmlString().doIndentDocument(xml);
}
}