如何在使用JAXB进行编组时添加DOCTYPE和xml处理指令?

我正在将JAXB bean编组(序列化)为输出流。 如何添加DOCTYPE声明和xml处理指令以进行输出?

我正在做这样的编组:

JAXBContext jaxbContext = JAXBContext.newInstance("com.example.package"); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = schemaFactory.newSchema(schemaSource); marshaller.setSchema(schema); marshaller.marshal(object, output); 

我想要输出看起来像这样:

    

JAXB bean是生成的代码,所以我不想更改它们。

有一些hacks和无证技巧(请参阅使JAXB生成XML处理指令 )来添加xml处理指令和doctype 。 但是这样做的首选或正确方法是什么?

JAXB RI具有专有的Marshaller属性com.sun.xml.bind.xmlHeaders (请参阅XML Preamble控件 :

此属性允许您指定XML前导码( 声明)以及其后的任何其他PI,注释, DOCTYPE声明。 只有在编组为OutputStreamWriterStreamResult时,此属性才会生效。 请注意,此属性与Marshaller.JAXB_FRAGMENT属性进行交互。 如果该属性未被触及或设置为false,则JAXB将始终编写其XML前导码,因此此属性仅可用于编写PI,注释, DOCTYPE等。另一方面,如果将其设置为true,则JAXB不会编写自己的XML前导码,因此该属性可能包含自定义XML前导码。

这应该做你需要的。 如果您正在使用Java5和JAXB RI,那么这应该可行。 如果您使用Java6及其包含的JAXB实现,则com.sun.xml.bind.xmlHeaders名称可能不同,因此请尝试使用com.sun.xml.internal.bind.xmlHeaders