JAXBでCDATAセクションの出力
JAXBのUnmarshalerを使用してXML出力を行うと、CDATAセクションは使用されません。
https://jaxb.dev.java.net/faq/JaxbCDATASample.java
では、org.apache.xml.serialize.XMLSerializer を使った方法が紹介されていますが、XMLSerializer は deprecated なので、できれば他の方法が望ましいです。
ここでは javax.xml.stream.XMLEventWriter を使う方法を紹介します。
XMLEventWriterではXMLの出力を、「XMLのイベントを書き込む」という形で実現します。
JAXBのMarshalerからこのXMLEventWriterに出力をすることができるのですが、そのXMLのイベントを補足して書き換えることによって、CDATAセクションの出力を実現します。
以下はサンプルです。
すべての「文字列を出力する」XMLイベントを、「CDATAセクションを出力する」XMLイベントに書き換えています。
public class CDataEventWriterAdapter implements XMLEventWriter { /** * XMLEventWriter */ private XMLEventWriter writer; /** * @param writer */ public CDataEventWriterAdapter(XMLEventWriter writer) { this.writer = writer; } @Override public void add(XMLEvent event) throws XMLStreamException { if (event.isCharacters()) { event = XMLEventFactory.newInstance() .createCData(event.asCharacters().getData()); } writer.add(event); } .... }
このアダプタークラスを、Unmarshalerの出力時に使用します。
JAXBContext context = JAXBContext.newInstance(XXX.class); Marshaler marshaler = context.createMarshaler(); StringWriter writer = new StringWriter(); XMLEventWriter xmlEventWriter= XMLOutputFactory.newInstance().createXMLEventWriter(writer); marshaller.marshal(model, new CDataEventWriter(xmlEventWriter));
すべての文字列がCDATAセクションで囲まれて出力されます。