使用以下简单代码:
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());
}
}
我得到了输出:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Document comment --><!DOCTYPE aaa SYSTEM "testing.dtd">
<aaa>
<bbb/>
<ccc/>
</aaa>
问题A:doctype标签出现在文档注释之后。是否可以使其出现在文档评论之前?
问题B:如何仅使用JavaSE 5.0 API实现缩进? 此问题基本上与How to pretty-print xml from java相同,然而该问题中的几乎所有答案都取决于外部库。唯一适用的答案(由名为Lorenzo Boccaccia的用户发布)仅使用java的api,基本上与上面发布的代码相同,但对我不起作用(如输出所示,我没有缩进)。
我猜你必须设置用于缩进的空格量,因为许多外部库的答案都有,但我找不到在java api中指定的位置。鉴于在java api中存在将缩进属性设置为“是”的可能性,必须能够以某种方式执行缩进。我只是无法弄清楚如何。
答案 0 :(得分:113)
缺少的部分是缩进量。您可以设置缩进和缩进量,如下所示:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
答案 1 :(得分:4)
一个小的util类作为例子......
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由xercesImpl从Apache Foundation提供。这是maven依赖:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
您可以在此处找到您最喜欢的构建工具的依赖项:http://mvnrepository.com/artifact/xerces/xercesImpl/2.11.0。
答案 2 :(得分:1)
你可能用XSLT file来美化一切。谷歌抛出了一些结果,但我无法评论他们的正确性。
答案 3 :(得分:0)
要使输出成为有效的XML文档,请执行。有效的XML文档必须以处理指令开头。有关更多详细信息,请参阅XML规范http://www.w3.org/TR/REC-xml/#sec-prolog-dtd。