StAX XML форматирование в Java

Возможно ли использовать StAX (в частности, woodstox) для форматирования выходного xml с помощью новых строк и вкладок, то есть в виде:


  
   someData
  

вместо:

someData

Если это невозможно в Вудстоксе, есть ли другие легковесные либы, которые могут это сделать?

10 ответов

Решение

Через JDK: transformer.setOutputProperty(OutputKeys.INDENT, "yes");,

Есть com.sun.xml.txw2.output.IndentingXMLStreamWriter

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));

Если вы используете API курсора StAX, вы можете сделать отступ для вывода, поместив XMLStreamWriter в прокси с отступом. Я попробовал это в моем собственном проекте, и он работал хорошо.

Использование JDK Transformer:

public String transform(String xml) throws XMLStreamException, TransformerException
{
    Transformer t = TransformerFactory.newInstance().newTransformer();
    t.setOutputProperty(OutputKeys.INDENT, "yes");
    t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    Writer out = new StringWriter();
    t.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));
    return out.toString();
}

Вместо того чтобы полагаться на класс com.sun..., который может исчезнуть (или переименовать в класс com.oracle...), я рекомендую загрузить служебные классы StAX с java.net. Этот пакет содержит класс IndentingXMLStreamWriter, который прекрасно работает. (Источник и Javadoc включены в загрузку.)

Как насчет StaxMate:

http://www.cowtowncoder.com/blog/archives/2006/09/entry_21.html

Хорошо работает с Woodstox, быстрым использованием памяти с небольшим объемом памяти (без встроенного дерева в памяти) и такими отступами:


SMOutputFactory sf = new SMOutputFactory(XMLOutputFactory.newInstance());
SMOutputDocument doc = sf.createOutputDocument(new FileOutputStream("output.xml"));
doc.setIndentation("\n ", 1, 2); // for unix linefeed, 2 spaces per level    
// write doc like:    
SMOutputElement root = doc.addElement("element1");    
root.addElement("element2").addCharacters("someData");    
doc.closeRoot(); // important, flushes, closes output

Если вы используете XMLEventWriter, то более простой способ сделать это:

XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLEventWriter writer = outputFactory.createXMLEventWriter(w);
        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
        Characters newLine = eventFactory.createCharacters("\n"); 
        writer.add(startRoot);
        writer.add(newLine);

Не уверен насчет Stax, но здесь недавно обсуждалась красивая печать XML

красивая печать XML из Java

это была моя попытка найти решение

Как красиво печатать XML из Java?

используя метод org.dom4j.io.OutputFormat.createPrettyPrint()

Если вы используете метод итерации (XMLEventReader), не можете ли вы просто присоединить символ новой строки '\n' к соответствующим XMLEvents при записи в ваш XML-файл?

В Spring Batch для этого требуется подкласс, так как этот JIRA BATCH-1867

public class IndentingStaxEventItemWriter<T> extends StaxEventItemWriter<T> {

  @Setter
  @Getter
  private boolean indenting = true;

  @Override
  protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException {
    if ( isIndenting() ) {
      return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
    }
    else {
      return super.createXmlEventWriter( outputFactory, writer );
    }
  }

}

Но это требует дополнительной зависимости, потому что Spring Batch не включает код для отступа вывода StAX:

<dependency>
  <groupId>net.java.dev.stax-utils</groupId>
  <artifactId>stax-utils</artifactId>
  <version>20070216</version>
</dependency>
Другие вопросы по тегам