How to add CDATA to certain fields with XStream

In: Uncategorized

19 Nov 2009

If you are using XStream to turn your Java objects to XML you may need to make some of those field values within a CDATA tag.  Here’s how you do it.

When creating a new instance of the XStream object instead of this:

XStream xstream = new XStream();

Do this:

XStream xstream = new XStream(

	new XppDriver() {
	    public HierarchicalStreamWriter createWriter(Writer out) {
		return new PrettyPrintWriter(out) {
		    boolean cdata = false;
		    public void startNode(String name, Class clazz){
			super.startNode(name, clazz);
			cdata = (name.equals("description") || name.equals("name"));
		    }
		    protected void writeText(QuickWriter writer, String text) {
			if(cdata) {
			    writer.write("<![CDATA[");
			    writer.write(text);
			    writer.write("]]>");
			} else {
			    writer.write(text);
			}
		    }
		};
	    }
	}
);

Note on line 9, I’m specifically wrapping the “name” and “description” fields in CDATA.  Just change this to whichever fields you need.

16 Responses to How to add CDATA to certain fields with XStream

Avatar

Hai-Long Nguyen

November 23rd, 2009 at 11:52 am

awesome… exactly what i needed

Avatar

Hai-Long Nguyen

November 23rd, 2009 at 12:28 pm

How can I modify this to use a custom XmlFriendlyReplacer??

I have database fields with underscores and don’t want them to look like double-underscores in the xml returned.

XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(”_-”, “_”));
works fine….

but If I try to do the same with your code it still results in double underscores.

Thanks!

Avatar

Reece

February 22nd, 2010 at 10:41 am

Brilliant, thanks very much, just what I was trying to figure out :)

Avatar

jurahim

March 19th, 2010 at 4:44 am

awesome!! great… thx

Avatar

cmduquer

April 9th, 2010 at 1:47 pm

how to unmarshall an xml produced using cdata?

Avatar

Yogendra

April 15th, 2010 at 2:55 pm

Try something like below

private XppDriver xppDriver = new XppDriver(new XmlFriendlyReplacer(”__”, “_”)) {
public HierarchicalStreamWriter createWriter(Writer out){
return new PrettyPrintWriter(out,super.xmlFriendlyReplacer()) {
protected void writeText(QuickWriter writer,String text) {
writer.write(”");
}
public void startNode(String name) {
super.startNode(name.replace(”__”, “_”));
}
};
}
};

XStream xStream = new XStream(xppDriver);

Avatar

Yogendra

April 15th, 2010 at 2:59 pm

private XppDriver xppDriver = new XppDriver(new XmlFriendlyReplacer(”__”, “_”)) {
public HierarchicalStreamWriter createWriter(Writer out){
return new PrettyPrintWriter(out,super.xmlFriendlyReplacer()) {
protected void writeText(QuickWriter writer,String text) {
writer.write(”<![CDATA[");
writer.write(text);
writer.write("]]>”);
}
};
}
};

XStream xStream = new XStream(xppDriver);

Avatar

anantha

March 22nd, 2011 at 6:44 pm

Awsome. Worked like charm

Avatar

dave

March 9th, 2012 at 10:01 am

Hi,

Out of curiosity, why are you over-riding PrettyPrintWriter.startNode(String, Class), rather than just the startNode(String) method?

The 2-parameters method is from the AbstractWriter class, whereas startNode(String) comes from the interface, and so seems like the safer option. Is there anything I’m missing?

Your version was fine until I introduced my own converter, which is using the HierarchicalStreamWriter interface, and thus calls startNode(String), and meant that I was bypassing the over-ridden method - not easy to track down!

Nonetheless, thanks for the tip - I still saved plenty of time over all :)

Avatar

pickles

March 9th, 2012 at 11:19 am

No you’re probably right about overriding the AbstractWriter class. I guess once I got it working for me I just stopped there :)

Avatar

Jasdeep Singh

March 13th, 2012 at 4:38 am

Thanks……… this is exactly what i needed :)

Avatar

original lipodrene

March 2nd, 2013 at 5:19 am

Can I simply just say what a comfort to find someone
who genuinely knows what they’re talking about on the internet. You actually know how to bring a problem to light and make it important. A lot more people ought to look at this and understand this side of your story. I was surprised you’re not more popular since you definitely possess the gift.

Avatar

Andrew

December 10th, 2013 at 4:33 pm

This is definitely a great start to the solution I need, but I need CDATA tags to be added dynamically based on REGEX matches for specific characters in my xml data. Any Thoughts or advice on an approach to that would be very helpful. Thank you.

Avatar

Chand

May 13th, 2014 at 6:39 pm

Hi could any one suggest, if few childs should be CDATA and dynamic value…
How to get this with XSTREAM.

Avatar

Arv

August 20th, 2014 at 1:24 pm

In else case it should invoke:
super.writeText(writer, text);
NOT
writer.write(text);

Avatar

free cccam

September 17th, 2018 at 3:42 pm

Ola
great share.
I think the best cccam server are those from fishbone cloud
I would like to see more posts like this
Thanks

Comment Form

About this blog

Nothing that notable about this blog. It's just going to be a place where we post random stuff.

Photostream

  • free cccam: Ola great share. I think the best cccam server are those from fishbone cloud I would like to see [...]
  • FirstSam: I see you don't monetize your blog, don't waste your traffic, you can earn additional cash every m [...]
  • Arv: In else case it should invoke: super.writeText(writer, text); NOT writer.write(text); [...]
  • Chand: Hi could any one suggest, if few childs should be CDATA and dynamic value... How to get this with X [...]
  • Andrew: This is definitely a great start to the solution I need, but I need CDATA tags to be added dynamical [...]