Jolie impression de sortie de javax.XML.transformer.Transformateur avec api java standard (Indentation et positionnement Doctype))

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 la sortie:

<?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 document comment. Est-il possible de le faire apparaître avant le Commentaire du document?

Question B: Comment obtenir l'indentation, en utilisant seulement L'API JavaSE 5.0? Cette question est essentiellement identique à la Façon dont à-peu-près d'impression 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 java, est fondamentalement égale au code affiché ci-dessus, mais ne fonctionne pas pour moi (comme indiqué dans la sortie, Je ne reçois aucune indentation).

je suppose que vous devez définir la quantité d'espaces à utiliser pour l'indentation, comme beaucoup de réponses avec les bibliothèques externes le font, mais je ne peux pas trouver où spécifiez cela dans l'api java. Étant donné que la possibilité de définir une propriété d'indentation à "Oui" existe dans l'api java, il doit être possible d'effectuer l'indentation d'une manière ou d'une autre. Je ne peux pas comprendre comment.

55
demandé sur Community 2009-08-12 12:04:03

4 réponses

la partie manquante est le montant du tiret. Vous pouvez définir l'indentation et le montant du tiret comme suit:

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
110
répondu Rich Seller 2009-08-12 08:12:26

une petite classe util comme exemple...

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 est fourni par xercesImpl de la Apache Foundation . Voici la dépendance maven:

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
</dependency>

vous pouvez trouver la dépendance de votre outil de construction préféré ici: http://mvnrepository.com/artifact/xerces/xercesImpl/2.11.0 .

4
répondu Rob 2018-07-03 19:35:04

vous pourriez probablement tout prétifier avec un fichier XSLT . Google affiche quelques résultats, mais je ne peux pas commenter leur exactitude.

1
répondu McDowell 2009-08-12 10:39:12

Pour faire la sortie d'un document XML valide PAS. 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.

0
répondu Oskar 2013-06-19 17:55:47