如何在Java中使用W3C DOM创建一个空的DOCTYPE?

时间:2012-05-25 04:39:49

标签: java xml dom doctype

我正在尝试使用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吗?

2 个答案:

答案 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个对象。