Solved

XSL - using CDATA or other to escape message otherwise seen as markup

Posted on 2013-06-25
8
427 Views
Last Modified: 2013-06-25
I'm trying to use CDATA to escape a block of text that would otherwise be interpreted as markup.

I have the following .xsl

  <xsl:template match="Response">
    <Request>
      MI
      <xsl:call-template name="strip-between-tags">
        <xsl:with-param name="str" select="."/>
      </xsl:call-template>        
    </Request>
  </xsl:template>
 
  <xsl:template name="strip-between-tags">
    <xsl:param name="str"/>  
    <xsl:if test="contains($str, '&lt;')">
      <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
      <xsl:value-of select="substring-before(substring-after($str, '&lt;'), '&gt;')"></xsl:value-of>
      <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
      <xsl:call-template name="strip-between-tags">
        <xsl:with-param name="str" select="substring-after($str, '&gt;')"/>
      </xsl:call-template>
    </xsl:if>
    <xsl:if test="not (contains($str, '&lt;'))">
      <xsl:text disable-output-escaping="yes"> &lt;X&gt; </xsl:text>
    </xsl:if>
  </xsl:template>  

    This is my input data that I'm feeding into the xsl:
<CommandRS Version="2003.XML1.0.1">
      <Response>MI&lt;X&gt; X IF SELECT NAME  &lt;CAD&gt;&lt; &gt;</Response>
</CommandRS>
 
 
  Produces output
<CommandRQ Version="2003.XML.0.1">
      <Request>MI<X><CAD>< > <X> </Request>
</CommandRQ>
 

However, the output is erroring out because of the message between the Request tags.
So I tried changing my xsl to include CDATA:

  <xsl:template match="Response">
    <Request>
     <![CDATA[
      
    MI
    <xsl:call-template name="strip-between-tags">
        <xsl:with-param name="str" select="."/>
      </xsl:call-template>
     
        ]]>
    </Request>
  </xsl:template>
 
but this would comment out my template call. Please advise on how I can escape the block of text using CDATA or other method.
 
I also tried
  <xsl:template match="Response">
    <Request>
      <xsl:text><![CDATA[ ]]></xsl:text>
    MI
    <xsl:call-template name="strip-between-tags">
        <xsl:with-param name="str" select="."/>
      </xsl:call-template>

    </Request>
  </xsl:template>
 
but the output never included the "![CDATA[". Not sure how to implement this into the xsl
0
Comment
Question by:badtz7229
  • 3
  • 3
  • 2
8 Comments
 
LVL 18

Expert Comment

by:zc2
ID: 39275141
Never tried that, but may be the "cdata-section-elements" attribute of the xsl:output element might help?
<xsl:output method="xml" cdata-section-elements="Request"/>
0
 

Author Comment

by:badtz7229
ID: 39275210
zc2:
how do you incorporate that. i just added that line in my   <xsl:template match="Response"> but it didn't like it.
0
 
LVL 60

Assisted Solution

by:Geert Bormans
Geert Bormans earned 250 total points
ID: 39275218
it is on the xsl:output you need to put that, have done that a lot, works well

  <xsl:output indent="yes" cdata-section-elements="Request"/>

(note: xsl:output is a top level element in case you haven't used it)

the result element is what you need to put there

but you also need to remove the disable-output-escaping if you do that

     <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
should be
     <xsl:text>&gt;</xsl:text>
0
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

 
LVL 18

Accepted Solution

by:
zc2 earned 250 total points
ID: 39275248
Put this xsl:output line right after the first root element's opening tag of the XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" cdata-section-elements="Request"/>

Open in new window

0
 

Author Comment

by:badtz7229
ID: 39275474
what's the diff between
<xsl:output method="xml" cdata-section-elements="Request"/>
and
 <xsl:output indent="yes" cdata-section-elements="Request"/>

method versus indent?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39275506
method says you are creating XML, but that is the default if you output a root element different from <html>, so not really required

indent=yes makes that the output is indented (so easier to view)

it is all different attributes to the output element
the output element organises teh serialisation

In this stylesheet
<xsl:output method="xml" indent="yes" cdata-section-elements="Request"/>
would be equivalent to
<xsl:output indent="yes" cdata-section-elements="Request"/>
0
 

Author Closing Comment

by:badtz7229
ID: 39275632
There was no need for me to remove the disable-output-escaping when i added <xsl:output indent="yes" cdata-section-elements="Request"/>

I saw same output.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39275754
mmh, I have do disagree with that last statement.
If you see no difference with msxml, then that means msxml does it wrong.
Saxon does it right, there is a little quirk in Xalan too

if you tell the serialiser to make an element having CDATA content, you tell it to put all text nodes in a CDATA section.
BUT... by setting the d-o-e to yes, you tell the serialiser NOT to escape the '<' on output. Essentialy that means that you are outputting a STAGO (start tag opener), not a '<' character. That is not text, so should not be treated as text and the CDATA section should stop before and restart after the '<'. Most processors do that right. I also tested msxml, and it does the wrong thing. But this really is in the grey areas of XSLT.

However, I see no reason why you would leave an erroneous construct in your stylesheet. It makes your stylesheet less portable and unpredictable.
For msxml there is no difference. But I suggest you get rid of the d-o-e in your stylesheet. It would then also do the right thing with other processors
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This is a how to build your own CSS3 slideshow and when I say CSS3 I mean just CSS with no javascript in sight! There a few examples online of how to do this but most just show you an example without any explanation, others make it more complicat…
When writing CSS, there are a few simple rules that will make your life easier.    1. Using ‘* {box-sizing:border-box;}’. Using this will wrap all your elements in a nice little compact box-model that will give you the width you want, like so... …
In this tutorial viewers will learn how add a full-size background image to a webpage using CSS3. Create a new HTML document with an internal stylesheet.: In CSS, define the html element to have a background image. Use a high resolution image.: In t…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question