tags:

views:

757

answers:

2

I have an XSLT file generating plain HTML. I need to wrap some elements in CDATA blocks, so intend to use cdata-section-elements. But, if the element I want to have contain CDATA is only one <p> on the page, how do I get it to not put CDATA in all the other <p> elements?

The input data is this:

<item>
  ...
  <g:category>Gifts under &amp;pound;10</g:category>
</item>

My XSL is:

<xsl:element name="a">
  <xsl:attribute name="href">productlist.aspx</xsl:attribute>
  <xsl:copy-of select="text()" />
</xsl:element>

I want this to render something like:

Gifts under £10

But all I get is:

Gifts under &pound;10
+2  A: 

Well assuming you have some way of targeting the <p> tag that you want to enclose in CDATA section, you could do something like:

<xsl:output method="xml" version="1.0" encoding="UTF-8" 
    indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="/">
 <xsl:apply-templates/>
</xsl:template>
<xsl:template match="p[@test = 'test']">
 <xsl:copy>
  <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
  <xsl:apply-templates/>
  <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
 </xsl:copy>
</xsl:template>

<xsl:template match="@*|node()">
 <xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>

In this case all <p> tags with an attribute test = 'test' will have CDATA applied to them, all other tags will just be output as normal.

James
Not *nice*, but workable, +1. I wonder why anyone would want to output certain elements as CDATA, and others of the same kind not - after all, the *data* is exactly the same, so why care for the serialized representation?
Tomalak
Thank you for your help, but this isn't working for me. The unusual characters are still being rendered but now with a trailing ]]>
Matt W
Probably your problem can't be solved with CDATA then. What characters are being displayed incorrectly?
James
Pavel Minaev
A: 

The code I have is:

<xsl:element name="a">
  <xsl:attribute name="href">
    product.aspx?prod=<xsl:copy-of select="title/text()" />
  </xsl:attribute>
  <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
  <xsl:copy-of select="g:price" /> - <xsl:copy-of select="title/text()" />
  <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
</xsl:element>
Matt W
For some reason I don't understand, the code is rendering a "greater than" character just after the <![CDATA[
Matt W
Can you edit your question, rather than posting this as an answer? Also, it is hard to say anything about your expectations without seeing the input data as well.
Pavel Minaev