I have a requirement in which i have XML like this
<programs>
<program>
<name>test1</name>
<instr><![CDATA[ some string ]]></instr>
</program>
<program>
<name>test2</name>
<instr><![CDATA[ some string ]]></instr>
</program>
</programs>
My program needs to unmarshal this to JAXB, do some processing and finally marshall back to xml. When I finally marshall the JAXB objects to xml, i get the as plain text without CDATA prefix. But to keep the xml intact I need to get the xml back with CDATA prefix. It seems JAXB doesnt suppor this directly. Is there a way to achieve this?
CDATA or not, this should not be a problem since the output from JAXB will be escaped if needed.
I've also had the same problem and while looking in SO I found this post. Since I'm generating my beans with xjc I did not want to add a @XmlCData in the generated code.
After looking a while for a good solution I finally found this post: http://javacoalface.blogspot.pt/2012/09/outputting-cdata-sections-with-jaxb.html
Which contains the following example code:
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
Document document =
docBuilderFactory.newDocumentBuilder().newDocument();
// Marshall the feed object into the empty document.
jaxbMarshaller.marshal(jaxbObject, document);
// Transform the DOM to the output stream
// TransformerFactory is not thread-safe
StringWriter writer = new StringWriter();
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer nullTransformer = transformerFactory.newTransformer();
nullTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
nullTransformer.setOutputProperty(
OutputKeys.CDATA_SECTION_ELEMENTS,
"myElement myOtherElement");
nullTransformer.transform(new DOMSource(document),
new StreamResult(writer));
It works pretty fine for me. Hope it helps others that land in this page looking for the same thing I was.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
You can use MOXy's @XmlCDATA
extension to force a text node to be wrapped with CDATA:
package blog.cdata;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlCDATA;
@XmlRootElement(name="c")
public class Customer {
private String bio;
@XmlCDATA
public void setBio(String bio) {
this.bio = bio;
}
public String getBio() {
return bio;
}
}
For More Information
- http://blog.bdoughan.com/2010/07/cdata-cdata-run-run-data-run.html
- http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html