58 votes

Impression jolie de la sortie de javax.xml.transform.Transformer avec seulement l'api java standard (Indentation et positionnement du Doctype)

En utilisant le code simple suivant :

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

}

J'obtiens le résultat :

<?xml version="1.0" encoding="UTF-8"?>
<!-- Document comment --><!DOCTYPE aaa SYSTEM "testing.dtd">

<aaa>
<bbb/>
<ccc/>
</aaa>

Question A : La balise doctype apparaît après le commentaire du document. Est-il possible de la faire apparaître avant le commentaire du document ?

Question B : Comment réaliser l'indentation, en utilisant uniquement l'API JavaSE 5.0 ? Cette question est essentiellement identique à Comment imprimer un fichier xml à partir de Java ? , cependant presque toutes les réponses à cette question dépendent de bibliothèques externes. La seule réponse applicable (postée par un utilisateur nommé Lorenzo Boccaccia) qui n'utilise que l'API de Java, est fondamentalement égale au code posté ci-dessus, mais ne fonctionne pas pour moi (comme le montre la sortie, je n'obtiens aucune indentation).

Je suppose que vous devez définir le nombre d'espaces à utiliser pour l'indentation, comme le font de nombreuses réponses avec des bibliothèques externes, mais je ne trouve pas où spécifier cela dans l'API Java. Étant donné que la possibilité de définir une propriété d'indentation sur "oui" existe dans l'API java, il doit être possible d'effectuer l'indentation d'une manière ou d'une autre. Mais je n'arrive pas à trouver comment.

119voto

Rich Seller Points 46052

La partie manquante est la quantité d'indentation. Vous pouvez définir l'indentation et la quantité d'indentation comme suit :

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);

5voto

Rob Points 31

Une petite classe utilitaire à titre d'exemple...

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);
}
}

1voto

McDowell Points 62645

Vous pourriez probablement tout embellir avec un Fichier XSLT . Google donne quelques résultats, mais je ne peux pas me prononcer sur leur exactitude.

0voto

Oskar Points 81

Pour que la sortie soit un document XML valide, NON. Un document XML valide doit commencer par une instruction de traitement. Voir la spécification XML http://www.w3.org/TR/REC-xml/#sec-prolog-dtd pour plus de détails.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X