Java:如何缩进Transformer生成的XML

Mik*_*ike 106 java xml transform indentation

我正在使用Java的内置XML转换器来获取DOM文档并打印出生成的XML.问题是尽管明确地设置了参数"indent",但它根本没有缩进文本.

示例代码

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

 }
}
Run Code Online (Sandbox Code Playgroud)

结果

<?xml version="1.0" encoding="UTF-8" standalone="no"?><a><b/></a>
Run Code Online (Sandbox Code Playgroud)

期望的结果

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<a>
 <b/>
</a>
Run Code Online (Sandbox Code Playgroud)

思考?

ada*_*ost 208

您需要启用'INDENT'并设置变压器的缩进量:

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

更新:


参考:如何在序列化之前从DOM中删除仅空白文本节点?

(非常感谢所有成员,特别是@ marc-novakowski,@ james-murty和@saad):

  • 对我来说,默认缩进为0似乎很愚蠢,但除了'INDENT = yes`之外,我还必须添加:`t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount" ,"2");` (68认同)
  • 如果有多个内部节点,你也可以缩进内部吗?只是使用它不会缩进内部节点. (4认同)
  • @lapo如果您的提供者是xalan(如果有效的话可能就是这样),那么它可以作为“org.apache.xml.serializer.OutputPropertiesFactory.S_KEY_INDENT_AMOUNT”使用 (2认同)

mab*_*bac 19

这些建议的解决方案都不适合我.所以我一直在寻找替代解决方案,最终成为前面提到的第二步和第三步的混合.

  1. 将indent-number设置为transformerfactory
  2. 启用变压器中的缩进
  3. 用作者(或bufferedwriter)包装otuputstream
//(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"));
Run Code Online (Sandbox Code Playgroud)

您必须执行(3)以解决xml处理代码的"错误"行为.

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

(如果我错误地引用了我的来源,请告诉我)

  • 最后一行中的"out"是指什么? (3认同)

rem*_*pod 14

以下代码适用于Java 7.我在变换器(而不是变压器工厂)上设置缩进(是)和缩进量(2)以使其正常工作.

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);
Run Code Online (Sandbox Code Playgroud)

@ mabac设置属性的解决方案对我不起作用,但@ lapo的评论证明是有帮助的.


小智 8

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

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");
Run Code Online (Sandbox Code Playgroud)


Vik*_*ury 6

对我来说添加DOCTYPE_PUBLIC有效:

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


小智 5

如果要缩进,则必须将其指定为TransformerFactory

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