开发者

JAXB marshalling and unmarshalling CDATA

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 开发者_Python百科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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜