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 <p>.
</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, 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.
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.
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.
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.
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.
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 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