[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Wrapping all elements in CDATA

Subject: Re: Wrapping all elements in CDATA
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 22 Apr 2004 09:50:35 +0100
xsl copy cdata
Hi Jesse,

> I get the expected output in MSXML and other parsers but in the
> latest version of Xalan (2.6.0) I get different results. What am I
> doing wrong and how can I correct this to work as expected with all
> parsers?

The reason that this is working differently (actually, correctly) in
Xalan is that Xalan isn't ignoring the whitespace-only text nodes in
your XML document. As a tree, you have:

  Person
   +- "&#xA;  "                   <- whitespace
   +- ContactInfo
   |   +- "&#xA;    "             <- whitespace
   |   +- Email
   |   |   +- "person@xxxxxxxx"
   |   +- "&#xA;    "             <- whitespace
   |   +- Phone
   |   |   +- "111-111-1111"
   |   +- "&#xA;  "               <- whitespace
   +- "&#xA;"                     <- whitespace

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

tells the processor that whenever it sees any kind of node (including
text nodes; the match pattern here should really be match="*|@*" to
prevent it from conflicting with your other template), it should copy
that node, then process all its attributes and element children, and
then process all its child text nodes.

So, for example, if this template is used on the ContactInfo element,
you're telling the processor to first process the Email and Phone
elements, and then process the child text nodes of the ContactInfo
element, of which there are three, all whitespace-only.

(Probably what you meant to do here is:

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

This will process the attributes and children of the matched element
in whatever order they appear, which means you won't get all the text
nodes clustered after the child elements.)

Your template for text nodes:

>    <xsl:template match="text()">
>      <xsl:value-of select="$CDATABegin" disable-output-escaping="yes"/>
>      <xsl:value-of select="." disable-output-escaping="yes"/>
>      <xsl:value-of select="$CDATAEnd" disable-output-escaping="yes"/>
>    </xsl:template>

wraps those text nodes in the CDATA delimiters, so you get:

> <ContactInfo>
> <Email><![CDATA[person@xxxxxxxx]]></Email>
> <Phone><![CDATA[111-111-1111]]></Phone><![CDATA[
>      ]]><![CDATA[
>      ]]><![CDATA[
>    ]]></ContactInfo>

The CDATA sections that come after the Phone element contain the
whitespace.

If whitespace-only text nodes aren't significant in your document
(they aren't in most data-oriented XML such as yours, but are in most
document-oriented XML), then you should strip them from the source
tree using the <xsl:strip-space> element at the top level of the
stylesheet:

<xsl:strip-space elements="*" />

This tells the processor to ignore all the whitespace-only text nodes
in all the elements of the document.

When I saw your stylesheet, I thought the problem was going to be the
disable-output-escaping, and the fact that it isn't supported in all
processors. Another way of achieving your goal while avoiding
disable-output-escaping would be to use the cdata-section-elements
attribute on <xsl:output>, and do:

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

Unfortunately, you have to list all the elements that can contain
(significant) text nodes rather than using a wildcard, so this will
only work if you know the markup language that your stylesheet needs
to work with.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.