вторник, 14 мая 2013 г.

Форматируем XML из строки


Иногда возникает необходимость отформатировать XML представленный в виде linarized строки (то есть без отступов и переводов строки) Для этого я использую следующие функции:

import java.io.ByteArrayOutputStream;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class XMLUtils {

 private static final Logger logger = Logger.getLogger(XMLUtils.class);

 /**
  * Возвращает переформатированную строку
  * 
  * @param inputString
  *            Строка содержащая неформатированный XML
  * @return Строка содержащая отформатированный XML
  */
 public static String formatXMLString(String inputString) {
  String outputString = "";
  try {
   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
   DocumentBuilder db = dbf.newDocumentBuilder();
   InputSource is = new InputSource(new StringReader(inputString));
   Document document = db.parse(is);
   outputString = documentToFormattedString(document);
  } catch (Exception ex) {
   logger.warn(ex.getMessage(), ex);
  }
  return outputString;
 }

 /**
  * Возвращает строковое представление Узла(Node) в форматированном виде
  * 
  * @param node
  *            Объект Node
  * @return Строка содержащая отформатированный XML
  */
 public static String documentToFormattedString(Node node) {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();

  try {
   DOMSource source = new DOMSource(node);
   StreamResult result = new StreamResult(baos);
   TransformerFactory transFactory = TransformerFactory.newInstance();
   Transformer transformer = transFactory.newTransformer();
   transformer
     .setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
   transformer.setOutputProperty(OutputKeys.METHOD, "xml");
   transformer.setOutputProperty(OutputKeys.INDENT, "yes");
   // Без данного параметра не работают отступы
   transformer.setOutputProperty(
     "{http://xml.apache.org/xslt}indent-amount", "2");
   transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

   transformer.transform(source, result);

  } catch (Exception ex) {
   logger.warn(ex.getMessage(), ex);
  }

  return new String(baos.toByteArray());
 }
}