Hello everyone. I am trying to implement CDATA wrapping of values conditionally in XSLT.
My requirements are:
- If the value contains <, >, &, ", ' then it must be wrapped in CDATA in the transformed output.
- if the value does not contain any of the above characters, it will not be wrapped in CDATA
- This logic will need to be implemented on many fields

Does anyone have any strategies on how to do this?

Recommended Answers

All 3 Replies

What you want to do is not supported by XSL because including these characters in your XML document renders the XML document invalid.

for testing

<?xml version="1.0" encoding="UTF-8"?>

<root>
				<item><![CDATA[<]]></item>
				<item><![CDATA[>]]></item>
				<item><![CDATA[&]]></item>
				<item><![CDATA["]]></item>
				<item><![CDATA[']]></item>
				<item>Mc Donold's
				</item>
				<item>Siegfried &amp; Roy
				</item>
				<item>a &gt;b
				</item>
				<item>a &lt;b
				</item>
</root>

xsl

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
	<xsl:apply-templates select="root"/>
</xsl:template>
<xsl:template match="root">
	<root>
		<xsl:apply-templates select="item"/>
	</root>
</xsl:template>
<xsl:template match="item">
	<item>
	<xsl:variable name="pos">'</xsl:variable>
	<xsl:choose>
	<xsl:when test="contains(.,'&lt;')">
		<xsl:value-of select="concat('&lt;![CDATA[',.,']]&gt;')"/>
	</xsl:when>
	<xsl:when test="contains(.,'&gt;')">
		<xsl:value-of select="concat('&lt;![CDATA[',.,']]&gt;')"/>
	</xsl:when>
	<xsl:when test="contains(.,'&amp;')">
		<xsl:value-of select="concat('&lt;![CDATA[',.,']]&gt;')"/>
	</xsl:when>
	<xsl:when test="contains(.,'&quot;')">
		<xsl:value-of select="concat('&lt;![CDATA[',.,']]&gt;')"/>
	</xsl:when>
	<xsl:when test="contains(.,$pos)">
		<xsl:value-of select="concat('&lt;![CDATA[',.,']]&gt;')"/>
	</xsl:when>
	<xsl:otherwise>
		<xsl:value-of select="."/>
	</xsl:otherwise>
	</xsl:choose>
	</item>
</xsl:template>
</xsl:stylesheet>

result

<?xml version="1.0" encoding="utf-8"?>
<root>
   <item>&lt;![CDATA[&lt;]]&gt;</item>
   <item>&lt;![CDATA[&gt;]]&gt;</item>
   <item>&lt;![CDATA[&amp;]]&gt;</item>
   <item>&lt;![CDATA["]]&gt;</item>
   <item>&lt;![CDATA[']]&gt;</item>
   <item>&lt;![CDATA[Mc Donold's
				]]&gt;</item>
   <item>&lt;![CDATA[Siegfried &amp; Roy
				]]&gt;</item>
   <item>&lt;![CDATA[a &gt;b
				]]&gt;</item>
   <item>&lt;![CDATA[a &lt;b
				]]&gt;</item>
</root>

Helmut Hagemann

What you want to do is not supported by XSL because including these characters in your XML document renders the XML document invalid.

Sorry that I was not clearer. I should have added "It is possble however to include these characters if you guard them with <![CDATA[ ... ]]. "

As I understand it, the OP wants to know how to detect these characters in a document using XSL and, if found, then add "<![CDATA[ ... ]]" guards. A totally different issue than you show in your example.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.