来自 javax.xml.transform.Transformer 的漂亮打印输出,只有标准的 java api(缩进和文档类型定位)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1264849/
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
Pretty-printing output from javax.xml.transform.Transformer with only standard java api (Indentation and Doctype positioning)
提问by Alderath
Using the following simple code:
使用以下简单代码:
package test;
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class TestOutputKeys {
public static void main(String[] args) throws TransformerException {
// Instantiate transformer input
Source xmlInput = new StreamSource(new StringReader(
"<!-- Document comment --><aaa><bbb/><ccc/></aaa>"));
StreamResult xmlOutput = new StreamResult(new StringWriter());
// Configure transformer
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(); // An identity transformer
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "testing.dtd");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(xmlInput, xmlOutput);
System.out.println(xmlOutput.getWriter().toString());
}
}
I get the output:
我得到输出:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Document comment --><!DOCTYPE aaa SYSTEM "testing.dtd">
<aaa>
<bbb/>
<ccc/>
</aaa>
Question A: The doctype tag appears after the document comment. Is it possible to make it appear before the document comment?
问题 A:doctype 标签出现在文档注释之后。是否可以让它出现在文档注释之前?
Question B: How do I achieve indentation, using only the JavaSE 5.0 API? This question is essentially identical to How to pretty-print xml from java, howeveralmost all answers in that question depend on external libraries. The only applicable answer (posted by a user named Lorenzo Boccaccia) which only uses java's api, is basically equal to the code posted above, but does not work for me (as shown in the output, i get no indentation).
问题 B:如何仅使用 JavaSE 5.0 API 实现缩进?这个问题本质上与How to Pretty-print xml from java 相同,但是该问题中的几乎所有答案都依赖于外部库。唯一适用的答案(由名为 Lorenzo Boccaccia 的用户发布)仅使用 java 的 api,基本上等于上面发布的代码,但对我不起作用(如输出所示,我没有缩进)。
I am guessing that you have to set the amount of spaces to use for indentation, as many of the answers with external libraries do, but I just cannot find where to specify that in the java api. Given the fact that the possibility to set an indentation property to "yes" exists in the java api, it must be possible to perform indentation somehow. I just can't figure out how.
我猜你必须设置用于缩进的空格量,就像外部库的许多答案一样,但我只是找不到在 java api 中指定的位置。鉴于在 java api 中存在将缩进属性设置为“是”的可能性,必须可以以某种方式执行缩进。我就是不知道怎么做。
回答by Rich Seller
The missing part is the amount to indent. You can set the indentation and indent amount as follow:
缺少的部分是缩进的数量。您可以按如下方式设置缩进和缩进量:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
回答by McDowell
回答by Rob
A little util class as an example...
以一个小工具类为例......
import org.apache.xml.serialize.XMLSerializer;
public class XmlUtil {
public static Document file2Document(File file) throws Exception {
if (file == null || !file.exists()) {
throw new IllegalArgumentException("File must exist![" + file == null ? "NULL"
: ("Could not be found: " + file.getAbsolutePath()) + "]");
}
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
return dbFactory.newDocumentBuilder().parse(new FileInputStream(file));
}
public static Document string2Document(String xml) throws Exception {
InputSource src = new InputSource(new StringReader(xml));
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
return dbFactory.newDocumentBuilder().parse(src);
}
public static OutputFormat getPrettyPrintFormat() {
OutputFormat format = new OutputFormat();
format.setLineWidth(120);
format.setIndenting(true);
format.setIndent(2);
format.setEncoding("UTF-8");
return format;
}
public static String document2String(Document doc, OutputFormat format) throws Exception {
StringWriter stringOut = new StringWriter();
XMLSerializer serial = new XMLSerializer(stringOut, format);
serial.serialize(doc);
return stringOut.toString();
}
public static String document2String(Document doc) throws Exception {
return XmlUtil.document2String(doc, XmlUtil.getPrettyPrintFormat());
}
public static void document2File(Document doc, File file) throws Exception {
XmlUtil.document2String(doc, XmlUtil.getPrettyPrintFormat());
}
public static void document2File(Document doc, File file, OutputFormat format) throws Exception {
XMLSerializer serializer = new XMLSerializer(new FileOutputStream(file), format);
serializer.serialize(doc);
}
}
XMLserializer is provided by xercesImpl from the Apache Foundation. Here is the maven dependency:
XMLserializer 由Apache Foundation 的xercesImpl 提供。这是maven依赖:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
You can find the dependency for your favourite build tool here: http://mvnrepository.com/artifact/xerces/xercesImpl/2.11.0.
您可以在此处找到您最喜欢的构建工具的依赖项:http: //mvnrepository.com/artifact/xerces/xercesImpl/2.11.0。
回答by Oskar
To make the output a valid XML document, NO. A valid XML document must start with a processing instruction. See the XML specification http://www.w3.org/TR/REC-xml/#sec-prolog-dtdfor more details.
要使输出成为有效的 XML 文档,NO。有效的 XML 文档必须以处理指令开头。有关更多详细信息,请参阅 XML 规范http://www.w3.org/TR/REC-xml/#sec-prolog-dtd。