2008-11-14 16 views
20

¿Es posible el uso de StAX (woodstox específicamente) para formatear la salida XML con saltos de línea y las pestañas, es decir en la forma:StAX formato XML en Java

 
<element1> 
    <element2> 
    someData 
    </element2> 
</element1> 

en lugar de:

<element1><element2>someData</element2></element1>

Si esto no es posible en woodstox, ¿hay otras libs livianas que puedan hacer esto?

Respuesta

8

A través del JDK: transformer.setOutputProperty(OutputKeys.INDENT, "yes");.

+0

El enlace al appr Oach pierde dos puntos después de https –

+3

@Josh El enlace está roto. Este enfoque se propone en SO: [Formatear archivo XML usando StAX] (http://stackoverflow.com/questions/2949203/formatting-xml-file-using-stax/2952945#2952945) – chepseskaf

+0

Agregué un poco más de contexto en mi respuesta: http://stackoverflow.com/a/38371920/480894 – Roland

1

Si está utilizando el método de iteración (XMLEventReader), ¿no puede adjuntar un nuevo carácter de línea '\ n' a los XMLEvents relevantes al escribir en su archivo XML?

4

¿Qué tal StaxMate:

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

funciona bien con Woodstox,, el uso rápido de poca memoria (no está en la memoria del árbol construido) y guiones de este modo:


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 

6

Si está utilizando la API de cursor StAX, puede sangrar la salida envolviendo el XMLStreamWriter en un indenting proxy. Intenté esto en mi propio proyecto y funcionó muy bien.

+0

+1 me alegra oír que funcionó para ti :) – ewernli

22

No es com.sun.xml.txw2.output.IndentingXMLStreamWriter

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

Excelente. Muchas gracias –

+0

por lo que puedo ver, el espacio de nombres tiene un error o se ha movido a com.sun.xml.internal.txw2.output. – epeleg

+0

@epeleg No, la versión "interna" se incluye con el JRE. Puede obtener la versión no interna al agregar JAXB-RI explícitamente como una dependencia. – dog

4

En lugar de confiar en un com.sun ... la clase que podrían desaparecer (o conseguir com.oracle renombrado ... clase), recomiendo descargar el StAX utility classes de java.net. Este paquete contiene una clase IndentingXMLStreamWriter que funciona bien. (Fuente y javadoc están incluidos en la descarga.)

0

Con Spring Batch esto requiere una subclase ya que este 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); 
    } 
    } 

} 

Pero esto requiere una dependencia additionnal porque Spring Batch no incluye el código para sangrar la salida StAX:

<dependency> 
    <groupId>net.java.dev.stax-utils</groupId> 
    <artifactId>stax-utils</artifactId> 
    <version>20070216</version> 
</dependency> 
+0

Intenté esto, pero cuando despliego mi aplicación en weblogic y ejecuto el trabajo, crea un archivo xml con en cada línea después de la etiqueta de cierre. ¿Cómo evitar esto? –

4

Uso el 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(); 
}