Добавить XML-комментарии в маршалированный файл

Я собираю объекты в XML-файл. Как я могу добавить комментарии в этот файл XML?

4 ответа

Решение

Я не вижу способа сделать это с одним JAXB. Тем не менее, я думаю, что вы можете использовать DOM, чтобы получить желаемый эффект:

final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document doc = builder.getDOMImplementation().createDocument(null, null, null);

final Binder<Node> binder = jaxbContext.createBinder();
binder.marshal(jaxbObject, doc);
final Comment comment = doc.createComment("This is a comment");
doc.appendChild(comment);

final DOMSource domSource = new DOMSource(doc);
// use System.out for testing
final StreamResult streamResult = new StreamResult(System.out);
final TransformerFactory tf = TransformerFactory.newInstance();
final Transformer serializer = tf.newTransformer();
serializer.transform(domSource, streamResult);

Где jaxbContext - это объект JAXBContext, с которым вы работаете, а jaxbObject - это объект, который нужно маршалировать. Этот образец просто добавляет комментарий в конец документа. В другом месте вам придется пройти через DOM через объект doc или использовать XPath, чтобы найти точный элемент, к которому вы хотите добавить комментарий, и использовать appendChild для него.

Вы можете добавлять комментарии сразу после преамбулы с помощью проприетарного свойства Marshaller com.sun.xml.bind.xmlHeaders ( см. Управление преамбулой XML)

Во включенной JAXB-реализации jdk1.6.0_29 свойство называется "com.sun.xml.internal.bind.xmlHeaders".

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

Итак, чтобы получить этот XML с тестовым комментарием после преамбулы:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Test Comment -->
<player>
    <name>Daniel</name>
    <birthday>1982-06-09T00:00:00+02:00</birthday>
</player>

Вы можете использовать этот Java-код:

JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("com.sun.xml.internal.bind.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);

Если кто-то придет к этому сейчас, как я только что сделал, стоит указать, что свойство сделать это сейчас com.sun.xml.bind.xmlHeaders (кажется, больше не внутренним), так что вы можете решить проблему следующим образом (я пробовал только с EclipseLink MOXY):

JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("com.sun.xml.bind.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);

Следующая информация изначально взята из Marshaller Properties в документации по JAXB RI Extensions на http://jaxb.java.net/:

Управление преамбулой XML

Это свойство позволяет указать преамбулу XML (объявление) и любые дополнительные PI, комментарии, объявление DOCTYPE, следующее за ним. Это свойство вступает в силу только тогда, когда вы выполняете маршалинг в OutputStream, Writer или StreamResult. Обратите внимание, что это свойство взаимодействует со свойством Marshaller.JAXB_FRAGMENT. Если это свойство не затронуто или установлено в false, то JAXB всегда будет писать свою преамбулу XML, поэтому это свойство можно использовать только для записи PI, комментариев, DOCTYPE и т. Д. С другой стороны, если для него установлено значение true, тогда JAXB не будет писать свою собственную преамбулу XML, поэтому это свойство может содержать собственную преамбулу XML.

JAXBContext Marshaller в последних версиях Java переносит некоторые свойства вorg.glassfish.jaxbВы можете использовать этот Java-код, чтобы добавить комментарии к вашему файлу:

      JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("org.glassfish.jaxb.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);

Посмотрите наsetProperty(String name, Object value)вMarshallerImpl.java

Другие вопросы по тегам