web-dev-qa-db-fra.com

Java: Comment mettre en retrait XML généré par Transformer

J'utilise le transformateur XML intégré de Java pour prendre un document DOM et imprimer le fichier XML résultant. Le problème est qu’il n’induit pas du tout le texte malgré le réglage explicite du paramètre "indent".

exemple de code

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 désiré

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

Pensées?

105
Mike

Vous devez activer 'INDENT' et définir le montant du retrait du transformateur:

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

Mise à jour:


Référence: Comment retirer un nœud de texte d'un espace réservé aux espaces blancs avant la sérialisation?

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

208
adatapost

Aucune des solutions suggérées n'a fonctionné pour moi. J'ai donc continué à chercher une solution alternative, qui était un mélange des deux précédentes et d'une troisième étape.

  1. définir le numéro d'indentation dans le transformateur
  2. activer l'indentation dans le transformateur
  3. encapsule le otuputstream avec un écrivain (ou un tampon)
//(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 le problème "buggy" du code de traitement XML.

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

(Si j'ai mal cité ma source, merci de me le faire savoir)

19
mabac

Le code suivant fonctionne pour moi avec Java 7.). Je règle l'indentation (oui) et l'indentation-montant (2) sur le transformateur (et non sur l'usine de transformation) pour le faire fonctionner.

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
remipod

importer com.Sun.org.Apache.xml.internal.serializer.OutputPropertiesFactory

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");
8
user2660852

J'ai utilisé la bibliothèque Xerces (Apache) au lieu de jouer avec Transformer. Une fois la bibliothèque ajoutée, 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
sevensevens

Si vous voulez l'indentation, vous devez le spécifier dans TransformerFactory.

TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer t = tf.newTransformer();
4
lucbelanger

Pour moi en ajoutant 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
Vikas Chowdhury