Discussion:
Need to wrap XML in <![CDATA[...]]> tags
Jason Cunningham
2003-08-04 14:18:38 UTC
Permalink
Hi,

I've got a strange requirement to transform

<sample>
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
</sample>

into

<sample>
<person>
<![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
]]>
</person>
</sample>

I've written this XSL

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>

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

<xsl:template match='*[name() = "sample"]'>
<sample>
<person>
<xsl:text disable-output-escaping="yes">
&lt;![CDATA[
</xsl:text>
<xsl:copy-of select="./node()"/>
<xsl:text disable-output-escaping="yes">
]]&gt;
</xsl:text>
</person>
</sample>
</xsl:template>

</xsl:stylesheet>

that gets me to

<sample>
<person>
&lt;![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
]]&gt;
</person>
</sample>

Unfortunately, this isn't good enough, for the system I am interfacing with.
I can not figure out how I can insert an unescapted '<' into the output -
I've read that '<' isn't allowed inside the xsl:text tag.

Has anyone any ideas?

Thanks for your time,

Jason

_________________________________________________________________
Find a cheaper internet access deal - choose one to suit you.
http://www.msn.co.uk/internetaccess


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Matt Trimmer
2003-08-04 14:34:58 UTC
Permalink
Hi,

I have a similar requirement and I thought you could do it with
cdata-section-elements.

I want to make the following whole CONTENT section be enclosed in a CDATA
section but the cdata-section-elements doesn't seem to do it. Is there
something else I should use to make a whole tree CDATA?


<?xml version="1.0" ?>
- <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" cdata-section-elements="TITLE
CONTENT" />
- <xsl:template match="dataroot">
- <DATA SERIAL="200307271225">
- <xsl:for-each select="Source">
- <ITEM>
- <URL>
<xsl:value-of select="URL" />
</URL>
- <LINK>
http://www.site.com<xsl:value-of select="PARAM"
/>&referredURL=<xsl:value-of select="URL" />
</LINK>
- <TITLE> <xsl:value-of select="Title" /></TITLE>
- <CONTENT>
- <html>
- <head>
- <title>
<xsl:value-of select="Title" />
</title>
- <body>
<xsl:value-of select="Body" />
</body>
</head>
</html>
</CONTENT>
....etc


Matt








-----Original Message-----
From: owner-xsl-***@lists.mulberrytech.com
[mailto:owner-xsl-***@lists.mulberrytech.com] On Behalf Of Jason Cunningham
Sent: 04 August 2003 15:19
To: XSL-***@lists.mulberrytech.com
Subject: [xsl] Need to wrap XML in <![CDATA[...]]> tags


Hi,

I've got a strange requirement to transform

<sample>
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
</sample>

into

<sample>
<person>
<![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
]]>
</person>
</sample>

I've written this XSL

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>

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

<xsl:template match='*[name() = "sample"]'>
<sample>
<person>
<xsl:text disable-output-escaping="yes">
&lt;![CDATA[
</xsl:text>
<xsl:copy-of select="./node()"/>
<xsl:text disable-output-escaping="yes">
]]&gt;
</xsl:text>
</person>
</sample>
</xsl:template>

</xsl:stylesheet>

that gets me to

<sample>
<person>
&lt;![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
]]&gt;
</person>
</sample>

Unfortunately, this isn't good enough, for the system I am interfacing with.

I can not figure out how I can insert an unescapted '<' into the output -
I've read that '<' isn't allowed inside the xsl:text tag.

Has anyone any ideas?

Thanks for your time,

Jason

_________________________________________________________________
Find a cheaper internet access deal - choose one to suit you.
http://www.msn.co.uk/internetaccess


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-08-04 14:54:15 UTC
Permalink
Post by Matt Trimmer
I want to make the following whole CONTENT section be enclosed in a CDATA
section but the cdata-section-elements doesn't seem to do it. Is there
something else I should use to make a whole tree CDATA?
CDATA element sections mean that you lineraise a < element as < rather
than &lt; but you need to make your stylesheet write the < characters
to teh output. If you copy element nodes to the output then
cdata-section-elements will have no effect.


David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Matt Trimmer
2003-08-04 15:49:47 UTC
Permalink
Hi David,

Thanks for your reply, but I am not sure I understand. All I want to do is
go from this output

<CONTENT>
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>
</CONTENT>

to this:

<CONTENT><![CDATA[
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>]]>
</CONTENT>









-----Original Message-----
From: owner-xsl-***@lists.mulberrytech.com
[mailto:owner-xsl-***@lists.mulberrytech.com] On Behalf Of David Carlisle
Sent: 04 August 2003 15:54
To: xsl-***@lists.mulberrytech.com
Subject: Re: [xsl] Need to wrap XML in <![CDATA[...]]> tags
Post by Matt Trimmer
I want to make the following whole CONTENT section be enclosed in a
CDATA section but the cdata-section-elements doesn't seem to do it. Is
there something else I should use to make a whole tree CDATA?
CDATA element sections mean that you lineraise a < element as < rather than
&lt; but you need to make your stylesheet write the < characters to teh
output. If you copy element nodes to the output then cdata-section-elements
will have no effect.


David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The service
is powered by MessageLabs. For more information on a proactive anti-virus
service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-08-04 16:12:23 UTC
Permalink
Hi David,

Thanks for your reply, but I am not sure I understand. All I want to do is
go from this output

<CONTENT>
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>
</CONTENT>

to this:

<CONTENT><![CDATA[
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>]]>
</CONTENT>



Ah then I gave the right answer to the wrong question.

You can't have the requested result as it is not well formed XML. A
CDATA marked section can not contain the string ]]> except as its end
marker, so in particuar they don't nest.

your requested output has a <CONTENT> start tag, then some text content
then a closing </title> tag so would be a fatal error at that point.

You have to try vey hard to persuade XSLT to produce non well formed
output. Are you sure that's what you want?

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Matt Trimmer
2003-08-04 16:37:39 UTC
Permalink
I love and hate XSLT at the same time. I could probably live without the
title and body not being CDATA as well, but the format I have been requested
to build is defiantly one with the whole <CONTENT> tree in CDATA:

End result:

<CONTENT><![CDATA[
<html>
<head>
<title>Resultant text from a value-of</title>
<body>Resultant text from a value-of</body>
</head>
</html>]]>
</CONTENT>

.xsl

<CONTENT>
<html>
<head>
<title><xsl:value-of select="TITLE"></title>
<body><xsl:value-of select="BODY"></body>
</head>
</html>
</CONTENT>





-----Original Message-----
From: owner-xsl-***@lists.mulberrytech.com
[mailto:owner-xsl-***@lists.mulberrytech.com] On Behalf Of David Carlisle
Sent: 04 August 2003 17:12
To: xsl-***@lists.mulberrytech.com
Subject: Re: [xsl] Need to wrap XML in <![CDATA[...]]> tags




Hi David,

Thanks for your reply, but I am not sure I understand. All I want to do
is
go from this output

<CONTENT>
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>
</CONTENT>

to this:

<CONTENT><![CDATA[
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>]]>
</CONTENT>



Ah then I gave the right answer to the wrong question.

You can't have the requested result as it is not well formed XML. A CDATA
marked section can not contain the string ]]> except as its end marker, so
in particuar they don't nest.

your requested output has a <CONTENT> start tag, then some text content then
a closing </title> tag so would be a fatal error at that point.

You have to try vey hard to persuade XSLT to produce non well formed output.
Are you sure that's what you want?

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The service
is powered by MessageLabs. For more information on a proactive anti-virus
service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-08-04 16:58:28 UTC
Permalink
End result:

<CONTENT><![CDATA[
<html>
<head>
<title>Resultant text from a value-of</title>
<body>Resultant text from a value-of</body>
</head>
</html>]]>
</CONTENT>


OK then my first answer holds.
The above is exactly the same as

&lt;CONTENT>
&lt;html>
&lt;head>
&lt;title>Resultant text from a value-of&lt;/title>
&lt;body>Resultant text from a value-of&lt;/body>
&lt;/head>
&lt;/html>
</CONTENT>


Just linearised differently, just as <a="b"/> is the same as <a = 'b' />
AN XSLT (or any XML) system would see these as the same input,
and in XSLT you use identical code to produce either of them (and the
system will do it one way or the other, just as you can't directy
control whether the system uses " or ' around attribute values.

When using XSLT it's best not to think of the serialisation at all
until the final stage when you can drop serialisation hints to
xsl:output.

So you want to convert elements such as html into strings with their
linearisation. there are loads of stylesheets to do this in the faq or
archives of this list, and elswehere but they all basically look like
the code I posted before

<xsl:element match="*">
&lt;<xsl:value-of select="name()"/>&gt;
<xsl:apply-templates/>
&lt;/<xsl:value-of select="name()"/>&gt;
</xsl:element>

So once you've converted all your input tree to a single string, you
want to _ask_ the XSLt system to output that using CDATA rather than lots
of &lt; so you do that by

<xsl:output cdata-section-elements="CONTENT"/>

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Mattison
2003-08-04 17:19:42 UTC
Permalink
I've been doing some reports and wondering what experience folks have had
with the speed of using xsl:sort. So far I haven't observed any noticable
difference between sorting in the database query (putting the records in
the order in them xml) and letting xsl sort unorder records. But so far
I've only dealt with relatively small number or records so I'm not
surprised I don't notice a difference.

What suggestions or rules of thumb do folks use when deciding where to do
their sorting? As such things might matter the xsl parser and databases
are MSXML 4.0 and MS SQL respectively.

Mattison


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-08-04 18:09:52 UTC
Permalink
Generally speaking, when you use XSLT or any other language to process
the result of a database query, you should delegate as much of the
processing to the database engine as you can.

Michael Kay
Post by Matt Trimmer
-----Original Message-----
Sent: 04 August 2003 18:20
Subject: [xsl] sorting preformance
I've been doing some reports and wondering what experience
folks have had with the speed of using xsl:sort. So far I
haven't observed any noticable difference between sorting in
the database query (putting the records in the order in them
xml) and letting xsl sort unorder records. But so far I've
only dealt with relatively small number or records so I'm not
surprised I don't notice a difference.
What suggestions or rules of thumb do folks use when deciding
where to do their sorting? As such things might matter the
xsl parser and databases are MSXML 4.0 and MS SQL respectively.
Mattison
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-08-04 18:08:04 UTC
Permalink
the
format I have been requested to build is defiantly one with
Well, CDATA cannot contain a tree, so tell the person who set you the
requirement that it's nonsensical.

Michael Kay


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-08-04 18:02:47 UTC
Permalink
Post by Matt Trimmer
Thanks for your reply, but I am not sure I understand. All I
want to do is go from this output
<CONTENT>
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>
</CONTENT>
<CONTENT><![CDATA[
<html>
<head>
<title><![CDATA[Bla Bla]]></title>
<body><![CDATA[Bla Bla]]></body>
</head>
</html>]]>
</CONTENT>
The output you are trying to produce is not XML. A CDATA section cannot
contain a nested CDATA section (specifically, the first "]]>" terminates
the CDATA section, and the </title> will then be reported as an
unmatched end tag).

You are having coding problems because the design is bad - you need to
get it changed.

Michael Kay


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-08-04 17:59:10 UTC
Permalink
Post by Matt Trimmer
I have a similar requirement and I thought you could do it
with cdata-section-elements.
I want to make the following whole CONTENT section be
enclosed in a CDATA section but the cdata-section-elements
doesn't seem to do it. Is there something else I should use
to make a whole tree CDATA?
You need to understand that the only thing you can have in CDATA is
text. CDATA is saying "the angle brackets in here might look like
markup, but they are actually ordinary characters". So having XML markup
inside a CDATA section is a contradiction in terms, and is always going
to give you problems.

Michael Kay


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-08-04 14:38:11 UTC
Permalink
<xsl:text disable-output-escaping="yes">
&lt;![CDATA[

You don't want to produce "<!CDATA" taht is a linearisation issue that
will be handled by teh system.

You want to convert an element node into the string "<foo/>"
ie you need templates like
<xsl:element match="*">
&lt;<xsl:value-of select="nam()"/>&gt;
<xsl:apply-templates/>
&lt;/<xsl:value-of select="nam()"/>&gt;
</xsl:element>

There are more complete stylesheets doing this in the archives of this
list and the faq.

then if for some reason you want your person element to use CDATA
section markup, specify
cdata-section-elements="person"
on xsl:output.

You don't (ever, almost) want to uuse disable-output-escaping. It looks
as if your system doesn't support it anyway, given the output you
showed. (It might not support cdata-section-elements either, but at
least if that is ignored the result will be equivalent to te result you
asked for, even if using a different markup.


David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-08-04 17:50:46 UTC
Permalink
Your solution would work if you were using an XSLT processor that
supported disable-output-escaping. It seems you aren't. The fact that
d-o-e is non-portable is one of the reasons we often give for avoiding
it.

Another approach might be to use saxon:serialize(), or an equivalent
home-grown extension function of your own.

Best solution would be to find the person who designed this XML
structure and get them to mend their ways. Or you could devise a
sanitary XML representation of the data, generate that, and then
postprocess it using non-XSLT techniques (e.g. change <cdata>...</cdata>
to
<![CDATA[...]]> using a text editor).

Michael Kay
Post by Matt Trimmer
-----Original Message-----
Jason Cunningham
Sent: 04 August 2003 15:19
Subject: [xsl] Need to wrap XML in <![CDATA[...]]> tags
Hi,
I've got a strange requirement to transform
<sample>
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
</sample>
into
<sample>
<person>
<![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
]]>
</person>
</sample>
I've written this XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:copy>
</xsl:copy>
</xsl:template>
<xsl:template match='*[name() = "sample"]'>
<sample>
<person>
<xsl:text disable-output-escaping="yes">
&lt;![CDATA[
</xsl:text>
<xsl:copy-of select="./node()"/>
<xsl:text disable-output-escaping="yes">
</xsl:text>
</person>
</sample>
</xsl:template>
</xsl:stylesheet>
that gets me to
<sample>
<person>
&lt;![CDATA[
<name>
<firstName>Mickey</firstName>
<lastName>Mouse</lastName>
</name>
</person>
</sample>
Unfortunately, this isn't good enough, for the system I am
interfacing with.
I can not figure out how I can insert an unescapted '<'
into the output -
I've read that '<' isn't allowed inside the xsl:text tag.
Has anyone any ideas?
Thanks for your time,
Jason
_________________________________________________________________
Find a cheaper internet access deal - choose one to suit you.
http://www.msn.co.uk/internetaccess
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Loading...