2012-07-28 63 views
10

Uso de Java, me gustaría tener un documento en el siguiente formato:Elimina espacios en blanco y saltos de línea a partir de XML en Java

<tag1> 
<tag2> 
    <![CDATA[ Some data ]]> 
</tag2> 
</tag1> 

y convertirlo a:

<tag1><tag2><![CDATA[ Some data ]]></tag2></tag1> 

He intentado lo siguiente, pero no me está dando el resultado que estoy esperando:

DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); 
dbfac.setIgnoringElementContentWhitespace(true); 
DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); 
Document doc = docBuilder.parse(new FileInputStream("/tmp/test.xml")); 

Writer out = new StringWriter(); 
Transformer tf = TransformerFactory.newInstance().newTransformer(); 
tf.setOutputProperty(OutputKeys.INDENT, "no"); 
tf.transform(new DOMSource(doc), new StreamResult(out)); 
System.out.println(out.toString()); 
+1

Puede tratar esto como un archivo de texto, abrirlo con un BufferedReader, leer cada línea y guardar su valor de recorte dentro de un StringBuilder, después de todo esto, use un BufferedWriter para guardar su archivo con los contenidos de StingBuilder. –

+2

Si está dispuesto a utilizar algo como Xerces-J, puede utilizar OutputFormat para no imprimir los resultados: http://xerces.apache.org/xerces-j/apiDocs/org/apache/xml/serialize/OutputFormat .html –

+1

Por cierto, la razón por la que 'setIgnoringElementContentWhitespace' no ayuda es porque debe usar la validación de XML Schema/DTD para que el analizador sepa qué espacio en blanco es ignorable. – jtahlborn

Respuesta

15

Solución de trabajo siguiendo las instrucciones en los comentarios de la pregunta por @Luiggi Mendoza.

public static String trim(String input) { 
    BufferedReader reader = new BufferedReader(new StringReader(input)); 
    StringBuffer result = new StringBuffer(); 
    try { 
     String line; 
     while ((line = reader.readLine()) != null) 
      result.append(line.trim()); 
     return result.toString(); 
    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
} 
+0

Tenga en cuenta que debe cerrar el BufferedReader después de su uso mediante ** finally ** o Java 8 [try-with-resources] (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) . – RikH

5

recursivamente atraviesa el documento. eliminar cualquier nodo de texto con contenido en blanco. recorte cualquier nodo de texto con contenido no en blanco.

public static void trimWhitespace(Node node) 
{ 
    NodeList children = node.getChildNodes(); 
    for(int i = 0; i < children.getLength(); ++i) { 
     Node child = children.item(i); 
     if(child.getNodeType() == Node.TEXT_NODE) { 
      child.setTextContent(child.getTextContent().trim()); 
     } 
     trimWhitespace(child); 
    } 
} 
+0

Esto elimina espacios en el nodo - el ejemplo no tiene espacios en los nodos de texto – Mark

+1

@Mark - en realidad lo hace. los contenidos de "tag2" implican nuevas líneas y espacios, y nuevas líneas y espacios al final. – jtahlborn

+1

¿por qué los votos a favor? esto hará exactamente lo que quiere el OP. – jtahlborn

-4

Pruebe este código. Los métodos read y write en FileStream ignoran el espacio en blanco y las sangrías.

try { 
    File f1 = new File("source.xml"); 
    File f2 = new File("destination.xml"); 
    InputStream in = new FileInputStream(f1); 
    OutputStream out = new FileOutputStream(f2); 

    byte[] buf = new byte[1024]; 
    int len; 
    while ((len = in.read(buf)) > 0){ 
    out.write(buf, 0, len); 
} 
in.close(); 
out.close(); 
System.out.println("File copied."); 
} catch(FileNotFoundException ex){ 
    System.out.println(ex.getMessage() + " in the specified directory."); 
    System.exit(0); 
} catch(IOException e7){ 
    System.out.println(e7.getMessage()); 
} 
+3

que es una manera fantástica de romper su archivo xml ... – jtahlborn

+4

Nunca trabaje en archivos XML con streams puros –

+1

Calidad de código WOOOW como decompiled, el código no elimina espacios en blanco –

4

como se documenta en an answer to another question, la función relevante sería DocumentBuilderFactory.setIgnoringElementContentWhitespace(), pero - como ya se ha señalado aquí - de que la función requiere el uso de un analizador de validación, lo que requiere un esquema XML, o algo así.

Por lo tanto, su mejor opción es recorrer el Documento que obtiene del analizador y eliminar todos los nodos del tipo TEXT_NODE (o aquellos TEXT_NODE que contienen solo espacios en blanco).

Cuestiones relacionadas