Utilizing cdata-section-elements in XSL

Album Cover: White Blood Cells

"Every breath that is in your lungs is a tiny little gift to me."
White Stripes / Dead Leaves and the Dirty Ground

Posted on February 12, 2008 3:21 PM in XML
Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.

If you're writing an XSLT that will transform one XML document into another, you may want to enforce that certain elements in your XML output contain CDATA sections. However, if you include CDATA sections directly in your XSLT, you'll likely find that the transformation process results in escaped text in the output.

As an example, if you included the following inside your XSL file:

<Description>
  <!CDATA[Paragraphs are represented by <p>.]]>
</Description>

...you'll likely see something like the following in your XML output:

<Description>
  Paragraphs are represented by &lt;p&gt;.
</Description>

To prevent this particular type of transformation from occurring, you should make use of the cdata-section-elements attribute of the <xsl:output> element. Along with the other, arguably more common attributes of the element that specify the output type (e.g. "xml" vs. "html"), the output encoding ("utf-8" vs. "utf-16"), etc., you can provide the name of elements in your XML output that should contain CDATA sections. If you wanted your <Description> node to contain the CDATA section, then, you might do something like the following:

<xsl:output
  method="xml"
  indent="yes"
  version="1.0"
  encoding="UTF-16"
  standalone="yes"
  cdata-section-elements="Description"
/>

Doing so will result in XML output that looks more like you intended:

<Description>
  <!CDATA[Paragraphs are represented by <p>.]]>
</Description>

For more information on using cdata-section-elements, see XSL element output.

Comments

Jeff Graves on June 23, 2008 at 2:36 PM:

It does not work. The content in the details tag should be wrapped in CDATA.

XML:
<parent_messages>
 <result>
  <code>OK</code>
  <details>
   <word_1> This </word_1>
  </details>
 </result>
 <result>
  <code>OK</code>
  <details>
   <word_2> statement </word_2>
  </details>
 </result>
</parent_messages>

XSLT:
<xsl:stylesheet version='1.0' xmlns:xsl='<a rel="nofollow" href="http://www.w3.org/1999/XSL/Transform" title="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>'>
 <xsl:output method="xml" indent="yes" cdata-section-elements="details"/>
  <xsl:template match="/">
   <result>
    <code>OK</code>
    <xsl:element name="details">
     <param>
      <name>word_1_2</name>
      <value> <xsl:value-of select="//word_1"/> <xsl:value-of select="//word_2"/></value>
     </param>
    </xsl:element>
    <details>
     <param>
      <name>word_1_2</name>
      <value> <xsl:value-of select="//word_1"/> <xsl:value-of select="//word_2"/></value>
     </param>
    </details>
   </result>
  </xsl:template>
</xsl:stylesheet>

OUTPUT:
<result>
 <code>OK</code>
 <details>
  <param>
   <name>word_1_2</name>
   <value> This statement </value>
  </param>
 </details>
 <details>
  <param>
   <name>word_1_2</name>
   <value> This statement </value>
  </param>
 </details>
</result>

Permalink

Bernie Zimmermann on June 24, 2008 at 7:52 AM:

Jeff, as far as I know, simply adding cdata-section-elements="details" to your XSLT won't magically make CDATA sections appear in your output. You actually have to include the CDATA information in your XSLT as well, so that it gets transferred to the output at transformation time. See my very first example in the original post above.

Permalink

Jeff Graves on June 26, 2008 at 11:25 AM:

Xsl transforms are supposed to ignore the content of a CDATA section which means you can not place queries in a CDATA section.

I am working on an application that receives XML data generated by an xsl transform. The data encapsulates more data for a second application. The encapsulated data is also XML (supposed to be stored in a CDATA section). I know that encapsulating XML is CDATA is normally frowned upon, but in order to validate the XML with a DTD it must be encapsulated in CDATA.

Permalink

Bernie Zimmermann on June 26, 2008 at 10:38 PM:

Jeff, I'm thoroughly confused by the scenario you described, but it doesn't take much to thoroughly confuse me. Further proof: my previous comment was off-the-mark. The CDATA in the first blockquote in my original post actually has nothing to do with the CDATA in the last blockquote in the post.

To follow up on the first point in your last comment, though, I do not believe it's true that an XSLT is meant to ignore the content of a CDATA section completely. If you mean that it is meant to ignore any XSLT rules or queries inside one, then yes, I agree with you.

Going back to your initial problem (based on your first comment), have you tried storing the contents of the details node in a variable in your transformation and then including the variable inside the details node? It seems like that way when it's time to output the content you'd be dealing with the literal translation rather than having to worry about any explicit queries. Just a thought.

Permalink

Jeff Graves on July 03, 2008 at 12:30 PM:

I FINALY found a solution to this problem.
If you're intrested I found it at
http://www.hannonhill.com/forum/viewtopic.php?f=2&t=208

It involves tricking the XSL transformer into putting the CDATA section into the output. This could actually lead to the XSLT outputting invalid XML if done wrong.

Permalink

Bollimuntha on February 11, 2009 at 10:56 PM:

Hi

We are trying to convert ADO persist XML into HTML. one of the XML tag contains CDATA. We are unable to generate HTML. We successed when we removed the tag which contains CDATA. can you suggest how to resolve this?

Thanks in Advance

Permalink

buddike on March 10, 2009 at 4:25 AM:

Hi Permalink,

Try with this.

<xsl:value-of
select="tag having CDATA section"
disable-output-escaping="yes"/>

Note: disabling-output-escaping will ensure its content transform which were in CDATA sections

I hope your XML look like this:

<tag><![CDATA[some contents]]></tag>

Best regards,

Buddike

Permalink

Matteo on March 20, 2009 at 4:04 AM:

Hi,

i have the same problem and I've solved in this way:

XML snippets moved to Pastebin

I hope will be useful.

Regards,
Matteo

Permalink

Michael on March 20, 2009 at 10:03 AM:

Thank you this helped me

Permalink

Senaka on May 13, 2011 at 2:21 AM:

Hi

You don’t need to add <!CDATA[specifically in your stylesheet (version 2.0) to get <!CDATA[in output XML. Following xsl tested with oracle XDK xslt processor and output as below. Hope this help.

XSL:
===
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" version="1.0"
encoding="UTF-8" standalone="yes"
cdata-section-elements="Description" />
<!-- Root template -->
<xsl:template match="/">
<Description>
<xsl:text>

sdfsdfsdfsdfsdfsafdasfdasdfsd
</xsl:text>
</Description>
</xsl:template>
</xsl:stylesheet>


Output XML:
=========
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<Description>

<![CDATA[sdfsdfsdfsdfsdfsafdasfdasdfsd]]>
</Description>

Permalink

Craig on November 17, 2011 at 6:03 PM:

Wow, thanks - this had me stumped, but your explanation solved it perfectly!

Permalink

Maxime on October 01, 2012 at 8:17 AM:

What if the CDATA section elements we want to declare are defined not by Qname, but by an attribute ?

Permalink

donate timeshares on August 17, 2016 at 1:10 AM:

Thanks for every other informative site. The place else may just I get that kind of information written in such an ideal means? I have a venture that I’m just now operating on, and I have been on the look out for such information.

Permalink

anxiety attack on August 17, 2016 at 9:05 PM:

Wow i can say that this is another great article as expected of this blog.Bookmarked this site..

Permalink

www.levitradosageus24.com/generic-levitra on August 19, 2016 at 4:23 AM:

nice bLog! its interesting. thank you for sharing....

Permalink

free instagram followers on August 31, 2016 at 12:58 AM:

This one is great. keep doing awesome!..

Permalink

get followers on instagram on September 04, 2016 at 12:00 AM:

Great article Lot's of information to Read...Great Man Keep Posting and update to People..Thanks get followers on instagram|get likes

Permalink

tutu helper apk on March 13, 2017 at 5:55 AM:

great post mate, thanks for the info.

Permalink

domodypb on May 15, 2017 at 5:23 AM:

Post Comments

If you feel like commenting on the above item, use the form below. Your email address will be used for personal contact reasons only, and will not be shown on this website.

Name:

Email Address:

Website:

Comments:

Check this box if you hate spam.