Как добавить инструкции обработки DOCTYPE и xml при сортировке с помощью JAXB?

Я собираю (сериализую) JAXB beans для вывода потока. Как я могу добавить инструкции 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);

Мне бы хотелось получить вывод, который выглядит примерно так:

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

JAXB bean - это сгенерированный код, поэтому я не хочу их изменять.

Есть некоторые хаки и недокументированные трюки (см. Создание JAXB для генерации инструкции по обработке XML), чтобы добавить xml и doctype. Но каков предпочтительный или правильный способ сделать это?

Ответы

Ответ 1

JAXB RI имеет собственное свойство Marshaller com.sun.xml.bind.xmlHeaders (см. XML Preamble Control:

Это свойство позволяет указать Преамбула XML (<?xml ...>декларация) и любые дополнительные ИП, комментарии, DOCTYPE, что следует за ним. Это свойство вступает в силу только когда вы собираете OutputStream, Writer или StreamResult. Обратите внимание, что это свойство взаимодействует с Marshaller.JAXB_FRAGMENT. Если это свойство нетронуто или установлено на false, тогда JAXB всегда будет писать его преамбула XML, поэтому это свойство может использоваться только для написания ИП, комментариев, DOCTYPE и т.д. С другой стороны, если он установлен в true, тогда JAXB не будет написать собственную преамбулу XML, так что это свойство может содержать пользовательский XML Преамбула.

Это должно делать то, что вам нужно. Если вы используете Java5 и JAXB RI, тогда это должно сработать. Если вы используете Java6 с включенной реализацией JAXB, имя com.sun.xml.bind.xmlHeaders может быть другим, поэтому попробуйте com.sun.xml.internal.bind.xmlHeaders.