Impresionante salida de javax.xml.transform.Transformer con solo api java estándar(sangría y posicionamiento de Doctype)
pretty-print (4)
La parte faltante es la cantidad para sangrar. Puede establecer la sangría y el sangría de la siguiente manera:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
Usando el siguiente código simple:
package test;
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class TestOutputKeys {
public static void main(String[] args) throws TransformerException {
// Instantiate transformer input
Source xmlInput = new StreamSource(new StringReader(
"<!-- Document comment --><aaa><bbb/><ccc/></aaa>"));
StreamResult xmlOutput = new StreamResult(new StringWriter());
// Configure transformer
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(); // An identity transformer
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "testing.dtd");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(xmlInput, xmlOutput);
System.out.println(xmlOutput.getWriter().toString());
}
}
Obtengo el resultado:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Document comment --><!DOCTYPE aaa SYSTEM "testing.dtd">
<aaa>
<bbb/>
<ccc/>
</aaa>
Pregunta A: la etiqueta doctype aparece después del comentario del documento. ¿Es posible hacer que aparezca antes del comentario del documento?
Pregunta B: ¿Cómo logro la indentación, usando solo la API de JavaSE 5.0? Esta pregunta es esencialmente idéntica a Cómo imprimir bastante xml desde Java , sin embargo , casi todas las respuestas en esa pregunta dependen de bibliotecas externas. La única respuesta aplicable (publicada por un usuario llamado Lorenzo Boccaccia) que solo utiliza la API de Java, es básicamente igual al código publicado anteriormente, pero no funciona para mí (como se muestra en la salida, no recibo sangría).
Supongo que tienes que establecer la cantidad de espacios para usar para la sangría, como lo hacen muchas de las respuestas con bibliotecas externas, pero no puedo encontrar dónde especificar eso en la API de Java. Dado el hecho de que la posibilidad de establecer una propiedad de sangría a "sí" existe en la API java, debe ser posible realizar sangría de alguna manera. Simplemente no puedo entender cómo.
Para hacer que la salida sea un documento XML válido, NO. Un documento XML válido debe comenzar con una instrucción de procesamiento. Consulte la especificación XML http://www.w3.org/TR/REC-xml/#sec-prolog-dtd para obtener más detalles.
Probablemente podrías embellecer todo con un archivo XSLT . Google arroja algunos resultados, pero no puedo comentar sobre su corrección.
Una pequeña clase de utilidades como ejemplo ...
import org.apache.xml.serialize.XMLSerializer;
public class XmlUtil {
public static Document file2Document(File file) throws Exception {
if (file == null || !file.exists()) {
throw new IllegalArgumentException("File must exist![" + file == null ? "NULL"
: ("Could not be found: " + file.getAbsolutePath()) + "]");
}
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
return dbFactory.newDocumentBuilder().parse(new FileInputStream(file));
}
public static Document string2Document(String xml) throws Exception {
InputSource src = new InputSource(new StringReader(xml));
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
return dbFactory.newDocumentBuilder().parse(src);
}
public static OutputFormat getPrettyPrintFormat() {
OutputFormat format = new OutputFormat();
format.setLineWidth(120);
format.setIndenting(true);
format.setIndent(2);
format.setEncoding("UTF-8");
return format;
}
public static String document2String(Document doc, OutputFormat format) throws Exception {
StringWriter stringOut = new StringWriter();
XMLSerializer serial = new XMLSerializer(stringOut, format);
serial.serialize(doc);
return stringOut.toString();
}
public static String document2String(Document doc) throws Exception {
return XmlUtil.document2String(doc, XmlUtil.getPrettyPrintFormat());
}
public static void document2File(Document doc, File file) throws Exception {
XmlUtil.document2String(doc, XmlUtil.getPrettyPrintFormat());
}
public static void document2File(Document doc, File file, OutputFormat format) throws Exception {
XMLSerializer serializer = new XMLSerializer(new FileOutputStream(file), format);
serializer.serialize(doc);
}
}
XMLserializer es provisto por xercesImpl de Apache Foundation . Aquí está la dependencia maven:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
Puede encontrar la dependencia de su herramienta de compilación favorita aquí: http://mvnrepository.com/artifact/xerces/xercesImpl/2.11.0 .