Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 20th, 2009, 10:23 PM
Registered User
 
Join Date: May 2009
Posts: 8
Thanks: 1
Thanked 0 Times in 0 Posts
Default CData not showing up when transforming

I have an xml feed that I have to create for indeed. Indeed data to be contained within CData.

I am using C# to convert a DataSet into a XmlDataDocument and then XmllCompiledTransform to transform the xslt into the output xml file.

Everything works perfectly with the exception of the CData wrappers. Everything comes back without the wrappers.

I even tried:
<title>&lt;![CDATA[<xsl:value-ofselect="title"/>]]&gt;</title>

But that comes out as
<title>&lt;![CDATA[The Job Title]]&gt;</title>

It is getting very frustrating and any help would be appreciated. Below is my xslt file. How can I make all values wrapped ing CData just like the country node below?

<?xmlversion="1.0"encoding="UTF-8" ?>
<
xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<
xsl:templatematch="NewDataSet">
<
source>
<
publisher>XYZ</publisher>
<
publisherurl>http://www.xyz.com</publisherurl>
<
lastBuildDate>Fri, 10 Dec 2008 22:49:39 GMT</lastBuildDate>
<
xsl:apply-templatesselect="Table"/>
</
source>
</
xsl:template>
<
xsl:templatematch="Table">
<
job>
<
title><xsl:value-ofselect="title" /></title>
<
date><xsl:value-ofselect="created_on" /></date>
<
referencenumber><xsl:value-ofselect="job_id"/></referencenumber>
<
company><xsl:value-ofselect="company_name"/></company>
<
city><xsl:value-ofselect="city"/></city>
<
state><xsl:value-ofselect="state"/></state>
<
country><![CDATA[US]]></country>
<
postalcode><xsl:value-ofselect="zip"/></postalcode>
<
description>
<
xsl:value-ofselect="summary"/>
</
description>
<
salary></salary>
<
education></education>
<
jobtype><xsl:value-ofselect="work_type"/></jobtype>
<
category></category>
<
experience></experience>
</
job>
</
xsl:template>
</xsl:stylesheet>
 
Old May 21st, 2009, 02:38 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

CDATA is not part of the XSLT/XPath data model - there are no CDATA nodes on the tree. CDATA is regarded purely as a lexical convenience for inputting XML that contains many escaped characters, rather like "caps lock" on the keyboard - you can't tell whether the data was entered with caps lock set, and you can't tell whether it was entered using CDATA either.

If you want to output all <country> elements as CDATA, you can request the serializer to do this using <xsl:output cdata-section-elements="country"/>. However, it seems a very odd thing to do: if the content is something like "us", there are no special characters to escape, and the CDATA wrapper is therefore pure noise. No sane XML application is going to care whether the text is wrapped in CDATA or not.

I am very suprised that

Code:
<title><![CDATA[<xsl:value-of select="title"/>]]></title>
should produce the output

Code:
<title><![CDATA[The Job Title]]></title>
I would expect it to produce

Code:
<title>&lt;xsl:value-of select="title"&gt;</title>
That's because CDATA means "character data" - it says treat special characters as ordinary characters, which means that the <xsl:value-of in a stylesheet is not recognized as an element, and therefore does not act as an XSLT instruction.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old May 21st, 2009, 08:41 AM
Registered User
 
Join Date: May 2009
Posts: 8
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Mr. Kay, I see you all over the internet with all things xsl. Thank you for replying!

Code:
<title><![CDATA[<xsl:value-of select="title"/>]]></title>
produces just that

Code:
<title><![CDATA[<xsl:value-of select="title"/>]]></title>
Because it is wrapped in the CDATA everything within is just ignored by the transformation.

I completly agree with you that wrapping something like US in CDATA is retarted. However this is the requirements of Indeed which is pretty widely used and I dont think they are going to change anything because I ask them to.

However, they do have reason for doing it. They are accepting tons and tons of records from probably thousands of different sites out there and the requirement to wrap everything in CDATA keeps someone from breakin the entire import because one record had bad characters in it.

Now I have a really hard time believing that XSLT/XPath data model does not handle CDATA but hey you are the expert!

It is something that I have to do so how do I do it?

I tried the <xsl:output cdata-section-elements="country"/> but it has zero effect on the transformation.
 
Old May 21st, 2009, 08:54 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Can you post minimal but complete well-formed samples of the XML and the stylesheet you use that demonstrate the problem that xsl:output cdata-section-elements="country" has no effect on the transformation result?
And how exactly do you run the transformation with XslCompiledTransform? Do you write the transformation result to a file?
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old May 21st, 2009, 09:11 AM
Registered User
 
Join Date: May 2009
Posts: 8
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Now, here is one option. I do not like it and it is my last resort but it works. (I do feel kinda like I am robbing peter to pay paul) :(

If I add the disable-output-escaping
<title><xsl:value-ofselect="title"disable-output-escaping="yes" /></title>

and then change my stored procedure (I do have a seperate procedure just for this data) to:
select'<![CDATA['+ j.title +']]>'as'title'
from job

it will output:
<title><![CDATA[Suzzie Homemaker]]></title>

Which is exactly what I want but very very ugly. If someone could please find the proper way of doing this it would be great! If not, this is my solution.

Last edited by johnw182; May 21st, 2009 at 09:13 AM.. Reason: character misplaced
 
Old May 21st, 2009, 09:22 AM
Registered User
 
Join Date: May 2009
Posts: 8
Thanks: 1
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by Martin Honnen View Post
Can you post minimal but complete well-formed samples of the XML and the stylesheet you use that demonstrate the problem that xsl:output cdata-section-elements="country" has no effect on the transformation result?
And how exactly do you run the transformation with XslCompiledTransform? Do you write the transformation result to a file?
XSLT File:
Code:
<?xmlversion="1.0"encoding="UTF-8" ?>
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:templatematch="NewDataSet">
<source>
<publisher>XYZ</publisher>
<publisherurl>http://www.xyz.com</publisherurl>
<lastBuildDate>Fri, 10 Dec 2008 22:49:39 GMT</lastBuildDate>
<xsl:apply-templatesselect="Table"/>
</source>
</xsl:template>
<xsl:templatematch="Table">
<job>
<title><xsl:value-ofselect="title" /></title>
<date><xsl:value-ofselect="created_on" /></date>
<referencenumber><xsl:value-ofselect="job_id"/></referencenumber>
<company><xsl:value-ofselect="company_name"/></company>
<city><xsl:value-ofselect="city"/></city>
<state><xsl:value-ofselect="state"/></state>
<country><![CDATA[US]]></country>
<postalcode><xsl:value-ofselect="zip"/></postalcode>
<description>
<xsl:value-ofselect="summary"/>
</description>
<salary></salary>
<education></education>
<jobtype><xsl:value-ofselect="work_type"/></jobtype>
<category></category>
<experience></experience>
</job>
</xsl:template>
</xsl:stylesheet>
XML Representation of the Dataset:
Code:
<?xmlversion="1.0"standalone="yes"?>
<NewDataSet>
<Table>
<job_id>4</job_id>
<title>Suzzie Homemaker</title>
<company_name>XYZ</company_name>
<city>Clayton</city>
<state>NC</state>
<zip>27527</zip>
<summary>sdsfdfdf</summary>
<wage_min>10.0000</wage_min>
<wage_max>13.0000</wage_max>
<wage_type>Hour</wage_type>
<work_status>Full Time</work_status>
<expires_on>2009-06-14T21:41:48.357-04:00</expires_on>
<created_on>2009-03-16T21:41:48.357-04:00</created_on>
</Table>
<Table>
<job_id>8</job_id>
<title>Suzzie Homemaker</title>
<company_name>XYZ</company_name>
<city>Clayton</city>
<state>NC</state>
<zip>27527</zip>
<summary>sdsfdfdf</summary>
<wage_min>10.0000</wage_min>
<wage_max>13.0000</wage_max>
<wage_type>Hour</wage_type>
<work_status>Full Time</work_status>
<expires_on>2009-06-14T09:41:48-04:00</expires_on>
<created_on>2009-03-16T09:41:48-04:00</created_on>
</Table>
</NewDataSet>
C#.NET Code (.NET 2.0):
Code:
DataSet data;
int job_count;
data = JobFeed.ReturnFeedData("indeed");
XmlDataDocument xmlDoc = newXmlDataDocument(data);
XslCompiledTransform xslTran = newXslCompiledTransform();
xslTran.Load("indeed.xslt"); // XSLT from above
XmlTextWriter writer = newXmlTextWriter("xslt_output.xml", System.Text.Encoding.UTF8);
xslTran.Transform(xmlDoc, null, writer);
writer.Close();
 
Old May 21st, 2009, 09:27 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

That stylesheet sample is not well-formed, there are a lots of spaces missing.
And it does not have any xsl:output cdata-section-elements list at all so how does that demonstrate its use does not have any effect?
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old May 21st, 2009, 09:30 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

And if you want to write to an XmlWriter with XslCompiledTransform and you want the xsl:output have any effect on that writer then you need
Code:
XmlDataDocument xmlDoc = newXmlDataDocument(data);
XslCompiledTransform xslTran = newXslCompiledTransform();
xslTran.Load("indeed.xslt"); // XSLT from above
using (XmlWriter xw = XmlWriter.Create("xslt_output.xml", xslTran.OutputSettings))
{
  xslTran.Transform(xmlDoc, null, xw);
  xw.Close();
}
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old May 21st, 2009, 09:41 AM
Registered User
 
Join Date: May 2009
Posts: 8
Thanks: 1
Thanked 0 Times in 0 Posts
Default

The wrox forum is playing with the spaces, just trust the fact that it is well-formed when I am using it.

And as for the cdata-section-elements, I took it out because it didnt have any effect on the output. When it was there it looked like:
<xsl:output cdata-section-elements="title date referencenumber"/>
even tried just:
<xsl:output cdata-section-elements="title"/>

It could also be that i was doing it wrong. I really cant see how the parser knows that "title" is the element: source>job>title when all I am telling it is "title".

Quote:
Originally Posted by Martin Honnen View Post
That stylesheet sample is not well-formed, there are a lots of spaces missing.
And it does not have any xsl:output cdata-section-elements list at all so how does that demonstrate its use does not have any effect?
 
Old May 21st, 2009, 09:47 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Which is exactly what I want but very very ugly.

You've been given a very ugly problem to solve by someone who is woefully ignorant about XML. You either have to educate them, or you have to give them an ugly solution.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Transforming XML From One Namespace to Another mail4kaja XSLT 1 November 10th, 2008 10:14 AM
Add a CDATA section; add nodeset to CDATA section kssudhish XSLT 3 January 3rd, 2008 07:13 AM
XSL transforming to TEXT suri_1811 XSLT 8 October 30th, 2006 05:02 AM
Exception when transforming using XSLT ksskumar XSLT 5 October 10th, 2006 06:20 AM
Exception when transforming using ksskumar XSLT 1 October 10th, 2006 02:33 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.