Показаны сообщения с ярлыком xml. Показать все сообщения
Показаны сообщения с ярлыком xml. Показать все сообщения

вторник, 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());
 }
}

среда, 13 марта 2013 г.

Функция, которая возвращает первый элемент типа Node.ELEMENT_NODE из SOAPBody

Возвращает первый элемент типа Node.ELEMENT из SOAPBody.
Необходима в случае отформатированного документа.
Тогда содержимое body представляет собой массив из трех Node:
Первая и последняя ноды представляют собой Node.TEXT_NODE с содержимым = "\n" или чем-то подобным (табуляции, переводы строки и т.п.).
Для получения значимого содержимого перебираем массив через body.getChildElements() и находим Node с типом Node.ELEMENT_NODE

/**
  * Возвращает первый элемент из SOAPBody
  * Необходимо в случае отформатированного документа, когда body.getFirstChild() == "\n"
  * @param body
  * @return
  */
 public Node getFirstChildElement(SOAPBody body) {
  @SuppressWarnings("unchecked")
  Iterator nodes = body.getChildElements();
  while (nodes.hasNext()) {
   Node currentNode = nodes.next();
   if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
    return currentNode;
   }
  }
  return null;
 }

Получаем строковое представление Узла(Node) в форматированном виде


    /**
     * Возвращает строковое представление Узла(Node) в форматированном виде
     *
     * @param node Объект Node
     * @return Строковое представление
     */
    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());
    }