Link to home
Start Free TrialLog in
Avatar of tesmc
tesmcFlag for United States of America

asked on

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

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
Avatar of zc2
zc2
Flag of United States of America image

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"/>
Avatar of tesmc

ASKER

zc2:
how do you incorporate that. i just added that line in my   <xsl:template match="Response"> but it didn't like it.
SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tesmc

ASKER

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?
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"/>
Avatar of tesmc

ASKER

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.
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