Java:如何缩进 Transformer 生成的 XML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1384802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:26:47  来源:igfitidea点击:

Java: How to Indent XML Generated by Transformer

javaxmltransformindentation

提问by Mike

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.

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

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?

想法?

采纳答案by adatapost

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

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

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?

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

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

(非常感谢所有成员,尤其是 @marc-novakowski、@james-murty 和 @saad)

回答by lucbelanger

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

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

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

回答by mabac

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
  2. 启用变压器中的缩进
  3. 用写入器(或缓冲写入器)包装 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"));

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

您必须执行 (3) 来解决 xml 处理代码的“错误”行为。

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

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

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

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

回答by remipod

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.

以下代码适用于 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);

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

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

回答by sevensevens

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

我使用了 Xerces (Apache) 库,而不是使用 Transformer。添加库后,添加以下代码。

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

回答by sevensevens

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

导入 com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory

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

回答by Vikas Chowdhury

For me adding DOCTYPE_PUBLICworked:

对我来说,添加DOCTYPE_PUBLIC工作:

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