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

2022-01-19 00:00:00 xml marshalling java jaxb

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

I am marshalling (serializing) JAXB beans to output stream. How can I add DOCTYPE declaration and xml processing instructions to ouput?

我目前正在这样编组:

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);

我希望输出看起来像这样:

I'd like have output that looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Something SYSTEM "some.dtd">
<?xml-stylesheet type="text/xsl" href="some.xsl"?>

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

JAXB bean are generated code so I don't want to change them.

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

There are some hacks and undocumented tricks (see Making JAXB generate an XML processing instruction) to add the xml processing instructions and doctype. But what is the preferred or right way to do this?

推荐答案

JAXB RI 有一个专有的 Marshaller 属性 com.sun.xml.bind.xmlHeaders(请参阅XML 前导控制:

The JAXB RI has a proprietary Marshaller property com.sun.xml.bind.xmlHeaders (see XML Preamble Control:

此属性允许您指定一个XML 前导码 (<?xml ...>声明)和任何其他 PI,注释,DOCTYPE 声明跟随它.该属性生效只有当你编组到OutputStreamWriter流结果.请注意,这属性与Marshaller.JAXB_FRAGMENT 属性.如果该属性未触及或设置为 false,则 JAXB 将始终写入它的 XML 序言,所以这个属性可以仅用于编写 PI、评论、DOCTYPE 等.另一方面,如果它设置为 true,则 JAXB 不会编写自己的 XML 序言,所以这个属性可能包含自定义 XML序言.

This property allows you to specify an XML preamble (<?xml ...> declaration) and any additional PIs, comments, DOCTYPE declaration that follows it. This property takes effect only when you are marshalling to OutputStream, Writer, or StreamResult. Note that this property interacts with the Marshaller.JAXB_FRAGMENT property. If that property is untouched or set to false, then JAXB would always write its XML preamble, so this property can be only used to write PIs, comments, DOCTYPE, etc. On the other hand, if it is set to true, then JAXB will not write its own XML preamble, so this property may contain custom XML preamble.

这应该可以满足您的需要.如果您使用的是 Java5 和 JAXB RI,那么这应该可以正常工作.如果您使用 Java6 及其包含的 JAXB 实现,则 com.sun.xml.bind.xmlHeaders 名称可能不同,因此请尝试 com.sun.xml.internal.bind.xmlHeaders 代替.

This should do what you need. If you're using Java5 and the JAXB RI, then this should just work. If you're using Java6 with its included JAXB implementation, the com.sun.xml.bind.xmlHeaders name might be different, so try com.sun.xml.internal.bind.xmlHeaders instead.

相关文章