As you can see, I've changed the xsl:output to make description and content:encoded into cdata section elements, but the funny thing is: only the FIRST <description> outputs properly, and that's not the one I wanted:
A CDATA section can only contain text, so the processor silently ignores your attempt to generate elements inside an element flagged for CDATA output.
You need to generate text-versions of the elements inside - take a look at this stylesheet - try to run it on any XML input document (even itself) to see the result:
<xsl:templatematch="/"> <output> <description> This is the first description element </description>
<mydata:free> <p> This is not being output as a CDATA Section </p> </mydata:free>
<mydata:free> <p> This should actually come out as CDATA </p> </mydata:free>
<mydata:free><![CDATA[ <p> This should actually come out as CDATA being no different from the above </p> ]]></mydata:free> </output>
</xsl:template>
</xsl:stylesheet>
Now, I don't know what your newsletterContent template looks like, but let's say I had a chunk of XML I needed to create as text for CDATA output, I'd create a template for it and set the mode attribute to 'text' or similar, and then do like this (include 'code' in the cdata-section-elements attribute):
Ps. I'm still having a really hard time understanding how apply-template works as opposed to simply calling a template which is almost like calling a function.
- but I'd only do that if I had like two or three things to output - it's a mess in XSLT just as it is in ASP/PHP...
Using the match="*" attribute only makes sense if you're otherwise using match templates and apply-templates, which I get the vibe you're not, so you should probably use the approach above (unless you really want to start pulling things apart). It really depends on the complexity of your newsletterContent template.
Thanks Criztian, was afraid of that. For now I got another tip to simply solve it: Use a template and only get the description content through an XSLT macro. Then you can enclose the whole description element in a CDATA block. This won't work for everybody, but it's fine for my purposes.
That's actually a neat solution - I often forget to think outside of the box because I develop 95% of my XSLT locally without server-side processing, so I wouldn't have thought of this.
It's great because you can (probably) leave the original XSLT that generates the content untouched.
Creating a RSS feed with CDATA element
So I'm creating an RSS feed and I need some elements to be enclosed in CDATA tag, description and content:encoded:
As you can see, I've changed the xsl:output to make description and content:encoded into cdata section elements, but the funny thing is: only the FIRST <description> outputs properly, and that's not the one I wanted:
What am I doing wrong?
Hi Sebastiaan,
A CDATA section can only contain text, so the processor silently ignores your attempt to generate elements inside an element flagged for CDATA output.
You need to generate text-versions of the elements inside - take a look at this stylesheet - try to run it on any XML input document (even itself) to see the result:
Now, I don't know what your newsletterContent template looks like, but let's say I had a chunk of XML I needed to create as text for CDATA output, I'd create a template for it and set the mode attribute to 'text' or similar, and then do like this (include 'code' in the cdata-section-elements attribute):
/Chriztian
Thanks for that, I am probably doing it wrong but the newsletterContent template looks a bit like this now:
It also calls a few other templates, do I need to put them into text mode as well?
Ps. I'm still having a really hard time understanding how apply-template works as opposed to simply calling a template which is almost like calling a function.
Ah, well, something happened when I changed it into this:
But, of course, <xsl:value-of select="$bla" /> in there will also be turned into plain text, so that doesn't help either..
So. Back to the hack, you mentioned something about disable-output-escaping... where and how would I use it?
Hi Sebastiaan,
You can always break out of a CDATA Section if you need to (kinda like what you'd do in the good old days with ASP or PHP):
- but I'd only do that if I had like two or three things to output - it's a mess in XSLT just as it is in ASP/PHP...
Using the match="*" attribute only makes sense if you're otherwise using match templates and apply-templates, which I get the vibe you're not, so you should probably use the approach above (unless you really want to start pulling things apart). It really depends on the complexity of your newsletterContent template.
/Chriztian
Thanks Criztian, was afraid of that. For now I got another tip to simply solve it: Use a template and only get the description content through an XSLT macro. Then you can enclose the whole description element in a CDATA block. This won't work for everybody, but it's fine for my purposes.
That's actually a neat solution - I often forget to think outside of the box because I develop 95% of my XSLT locally without server-side processing, so I wouldn't have thought of this.
It's great because you can (probably) leave the original XSLT that generates the content untouched.
/Chriztian
is working on a reply...