Java: comment indenter XML généré par Transformer

j'utilise le transformateur XML intégré à Java pour prendre un document DOM et imprimer le XML résultant. Le problème est qu'il n'indente pas le texte du tout malgré avoir défini explicitement le paramètre "indent".

code échantillon

public class TestXML {

 public static void main(String args[]) throws Exception {
  ByteArrayOutputStream s;

  Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
  Transformer t = TransformerFactory.newInstance().newTransformer();

  Element a,b;

  a = d.createElement("a");
  b = d.createElement("b");

  a.appendChild(b);

  d.appendChild(a);

  t.setParameter(OutputKeys.INDENT, "yes");

  s = new ByteArrayOutputStream();

  t.transform(new DOMSource(d),new StreamResult(s));

  System.out.println(new String(s.toByteArray()));

 }
}

résultat

<?xml version="1.0" encoding="UTF-8" standalone="no"?><a><b/></a>

résultat souhaité

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<a>
 <b/>
</a>

?

101
demandé sur Mike 2009-09-06 07:29:56

7 réponses

vous devez activer 'INDENT' et régler le montant de l'indent pour le transformateur:

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

mise à jour:


référence: comment dépouiller les noeuds texte Espace seulement d'un DOM avant la sérialisation?

(un grand merci à tous les membres en particulier @marc-novakowski, @james-murty et @saad) :

198
répondu adatapost 2017-05-23 12:09:57

aucune des solutions proposées ne me convenait. J'ai donc continué à chercher une solution alternative, qui s'est terminée par un mélange des deux avant mentionnées, et une troisième étape.

  1. placer le numéro de tiret dans le transformateur
  2. activer le tiret dans le transformateur
  3. envelopper le otuputstream avec un écrivain (ou bufferedwriter)
//(1)
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));

//(2)
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");

//(3)
t.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "utf-8"));

vous devez faire (3) pour contourner un comportement "buggy" de la code de manipulation xml.

Source: johnnymac75 @ http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446

(si j'ai mal cité ma source, veuillez me le faire savoir)

19
répondu mabac 2012-07-03 23:52:07

le code suivant fonctionne pour moi avec Java 7. J'ai mis le tiret (oui) et le tiret-montant (2) sur le transformateur (pas le transformateur) pour qu'il fonctionne.

TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(source, result);

la solution de @mabac pour définir l'attribut n'a pas fonctionné pour moi, mais le commentaire de @lapo s'est avéré utile.

14
répondu remipod 2014-03-04 17:57:30

import com.sun.org.apache.xml.interne.serializer.OutputPropertiesFactory

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");
8
répondu 2014-11-06 14:41:59

si vous voulez l'indentation, vous devez La spécifier au TransformerFactory .

TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer t = tf.newTransformer();
4
répondu lucbelanger 2009-12-04 21:39:00

j'ai utilisé la bibliothèque Xerces (Apache) au lieu de jouer avec le transformateur. Une fois que vous avez ajouté la bibliothèque, ajoutez le code ci-dessous.

OutputFormat format = new OutputFormat(document);
format.setLineWidth(65);
format.setIndenting(true);
format.setIndent(2);
Writer outxml = new FileWriter(new File("out.xml"));
XMLSerializer serializer = new XMLSerializer(outxml, format);
serializer.serialize(document);
4
répondu sevensevens 2013-05-06 18:56:29

pour moi ajouter DOCTYPE_PUBLIC travaillé:

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "10");
2
répondu Vikas Chowdhury 2016-08-12 12:31:58