This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: Escaping an apostrophe for JavaScript


Jeni and Robert,
"ack-ha!"

And you are right about ValidateOnParse. I have a generic LoadXML method
I call which by default turns on ValidateOnParse. I did this because I
had orignally had XML Schemas for each of my XML datasets (had to
convert them to XDR schmeas as MSXML3 doesn't yet support W3C xmlSchema
WD).

Thanks,
Frank O\'Connor


-----Original Message-----
From: Jeni Tennison [mailto:mail@jenitennison.com]
Sent: Sunday, February 25, 2001 3:37 AM
To: Frank T. O'Connor
Cc: xsl-list@lists.mulberrytech.com
Subject: Re: [xsl] Escaping an apostrophe for JavaScript


Hi Frank,

> I can't seem to figure out any way of using translate or substring
> to convert the apostrophe to a backslash-apostrophe. There doesn't
> seem to be any way to locate the location of a substring within a
> string. Unless I loop it one character at a time.

You don't have to go over it one character at a time, but you do have
to recurse over it in some way.  The following template does it for
you:

<xsl:template name="escape-apos">
   <xsl:param name="string" />
   <!-- create an $apos variable to make it easier to refer to -->
   <xsl:variable name="apos" select='"&apos;"'" />
   <xsl:choose>
      <!-- if the string contains an apostrophe... -->
      <xsl:when test='contains($string, $apos)' />
         <!-- ... give the value before the apostrophe... -->
         <xsl:value-of select="substring-before($string, $apos)" />
         <!-- ... the escaped apostrophe ... -->
         <xsl:text>\'</xsl:text>
         <!-- ... and the result of applying the template to the
                  string after the apostrophe -->
         <xsl:call-template name="escape-apos">
            <xsl:with-param name="string"
                            select="substring-after($string, $apos)" />
         </xsl:call-template>
      </xsl:when>
      <!-- otherwise... -->
      <xsl:otherwise>
         <!-- ... just give the value of the string -->
         <xsl:value-of select="$string" />
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

Things get a little more complicated if you need to escape other
characters as well (like double quotes and new lines).  You either
have three templates as above and call each on the result of the
previous, or have one template that recurses over both the bit before
and the bit after the relevant character.

> I was thinking perhaps I could make up a entity that is
> backslash-apostrophe, and then tell translate to replace apostrophe
> with this entity.

Entities are dealt with really low down the XML processing hierarchy.
The XSLT processor doesn't even see entities - all it sees is the
result of replacing an entity with the relevant string.

So if you have an entity:

  <!ENTITY test "\&apos;">

and then have:

  translate($string, "&apos;", "&test;")

then as far as the XSLT processor is concerned, this is *exactly* the
same as:

  translate($string, "'", "\'")

This will translate all apostrophes in your string with backslashes,
because the translate() function works on a character by character
basis.

Basically, you can't use translate() to search and replace anything
but single characters with other single characters.  You have to use a
recursive solution as above if you have something more complicated
than that.

> But I'm not sure where to put this DTD information in my XSL file. 
>
> I tried this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE xsl:stylesheet [
>         <!ENTITY test "\&apos;">
]>>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">>
> ...
> </xsl:stylesheet>
>
> but I get this error:
> The element 'xsl:stylesheet' is used but not declared in the
DTD/Schema

That's the right place to put it, but it looks as if putting the
DOCTYPE in a file automatically turns out a validating parser.  The
validating parser tries to validate the entire stylesheet (something
that is notoriously difficult, if not impossible), and gives you the
error because it comes across an element (xsl:stylesheet) that hasn't
been declared in the DTD.

Highly irritating if you just want to declare an entity.  I guess that
this is MSXML although I'm surprised because I thought they had
validation turned off by default.  You need to set validateOnParse to
false for the stylesheet.  Have a look at the MSXML SDK documentation
from msdn.microsoft.com for more details.

I hope that helps,

Jeni

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



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]