Java: How to Indent XML Generated by Transformer

人走茶凉 提交于 2019-12-27 11:38:57

问题


I'm using Java's built in XML transformer to take a DOM document and print out the resulting XML. The problem is that it isn't indenting the text at all despite having set the parameter "indent" explicitly.

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

 }
}

result

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

desired result

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

Thoughts?


回答1:


You need to enable 'INDENT' and set the indent amount for the transformer:

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

Update:


Reference : How to strip whitespace-only text nodes from a DOM before serialization?

(Many thanks to all members especially @marc-novakowski, @james-murty and @saad):




回答2:


Neither of the suggested solutions worked for me. So I kept on searching for an alternative solution, which ended up being a mixture of the two before mentioned and a third step.

  1. set the indent-number into the transformerfactory
  2. enable the indent in the transformer
  3. wrap the otuputstream with a writer (or 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"));

You must do (3) to workaround a "buggy" behavior of the xml handling code.

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

(If I have cited my source incorrectly please let me know)




回答3:


The following code is working for me with Java 7. I set the indent (yes) and indent-amount (2) on the transformer (not the transformer factory) to get it working.

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

@mabac's solution to set the attribute didn't work for me, but @lapo's comment proved helpful.




回答4:


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

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



回答5:


If you want the indentation, you have to specify it to the TransformerFactory.

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



回答6:


I used the Xerces (Apache) library instead of messing with Transformer. Once you add the library add the code below.

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



回答7:


For me adding DOCTYPE_PUBLIC worked:

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


来源:https://stackoverflow.com/questions/1384802/java-how-to-indent-xml-generated-by-transformer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!