我正在尝试使用W3C DOM API in Java读取XML文档并将其输出到新的XML文档中。要处理DOCTYPE,我使用以下代码(从输入文档doc
到目标文件target
):
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // omit '<?xml version="1.0"?>'
trans.setOutputProperty(OutputKeys.INDENT, "yes");
// if a doctype was set, it needs to persist
if (doc.getDoctype() != null) {
DocumentType doctype = doc.getDoctype();
trans.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
trans.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
}
FileWriter sw = new FileWriter(target);
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
对于包含和不包含DOCTYPE的XML文档,这都适用。但是,在尝试转换以下输入XML文档时,我现在遇到NullPointerException
:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE permissions >
<permissions>
// ...
</permissions>
HTML 5对其DOCTYPE使用类似的语法and it is valid。但我不知道如何使用W3C DOM API处理这个问题 - 尝试将DOCTYPE_SYSTEM
设置为null
会引发异常。我还可以使用W3C DOM API输出空的doctype吗?
答案 0 :(得分:4)
虽然这个问题已经有两年了,但它在某些网络搜索引擎中是一个热门搜索结果,所以也许它是一个有用的捷径。请参阅问题Set HTML5 doctype with XSLT,提及http://www.w3.org/html/wg/drafts/html/master/syntax.html#doctype-legacy-string,其中包含:
出于无法输出HTML标记的HTML生成器的目的 使用短DOCTYPE“
<!DOCTYPE html>
”, DOCTYPE遗产 字符串可以插入DOCTYPE [...]换句话说,
<!DOCTYPE html SYSTEM "about:legacy-compat">
或<!DOCTYPE html SYSTEM 'about:legacy-compat'>
,不区分大小写 除了单引号或双引号中的部分。
引出一系列像这样的Java代码:
trans.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "about:legacy-compat");
答案 1 :(得分:1)
尝试此处的建议https://stackoverflow.com/a/6637886/116509。基本上看起来它不能用标准的Java DOM支持来完成。
你也可以试试StAX
XMLStreamWriter xmlStreamWriter =
XMLOutputFactory.newFactory().createXMLStreamWriter( System.out, doc.getXmlEncoding() );
Result result = new StAXResult( xmlStreamWriter );
// ... create dtd String
xmlStreamWriter.writeDTD( dtd );
DOMSource source = new DOMSource( doc );
trans.transform( source, result );
但它很难看,因为DTD参数是String
,而你只有DocumentType
个对象。