(Quick edit: I think some of the HTML blocks I posted were escaped poorly in the blog post. I've got to run, but if so, I'll fix them later today. Second Edit - I replaced the badly formatted code examples with screen shots.) This came up on cf-talk (both the question and the answer from almost three years ago!) and I thought it would be good to share. Jake Munson noted that whenever he tried to insert HTML into an XML object, the HTML ended up escaped. Let's look at a quick example.


<cfset s = "<font color=""red""><b>foo</b></font>">
<cfxml variable="x">
<root>
<child name="one" />
</root>
</cfxml>
<cfset x.root.child[1].xmlText = s>

<cfoutput>
#htmleditformat(toString(x))#
</cfoutput>

We begin with the HTML we want to insert in variable s. Next we define a real simple and small XML string in x. So far so good. Next we insert s into x. What is the result?

As you can see, the HTML was escaped. That's not good. So what to do? When I first saw this, I brought up the fact that this is probably a feature. When you insert HTML into XML, you are normally supposed to wrap it in a CDATA block. CDATA blocks allow for any data, even bad XML, inside a valid XML block. As we know, HTML doesn't always follow proper XML works (or it should, but real world HTML doesn't always do so). I recommended simply wrapping up the string in CDATA like so:


<cfset x.root.child[1].xmlText = "<![CDATA[" &  s & "]]>">

How well does that work? Badly:

Finally I did some Googling, and ran across another cf-talk post, from 2008, by Chris Johnson. Turns out there is another way to set values. I was using the xmlText attribute, but there is actually an xmlCData attribute as well!


<cfset x.root.child[1].xmlCData =   s>

Which returns:

Perfect! And as Chris points out, this is actually documented. In all my years working with XML and ColdFusion, this is the first I've seen of this feature though. I hope this helps others.