Discussion:
Escaping quotes in XPath expressions
y***@yahoo.com.br
2003-11-15 12:55:22 UTC
Permalink
Hello all,

Can anyone please tell me how I can escape a single-quote in an XPath expression
such as the one below?

<xsl:value-of select="translate(normalize-space(.), 'x', 'y')"/>

If I use 'x' and 'y' as the search and replace arguments, everything works well. But I
need to search for single-quotes and replace them with backslash + single-quote. In
other words, my XPath expression would look something like this:

translate(normalize-space(.), ''', '\'')

Except, of course, that I can't use a single-quote (character) between two single-quotes
(string delimiters). Backslashes don't escape anything, of course, and using XML
entities (&quot;) inside the search and replace strings won't work either.

But I just feel there must be a way to do this...

Thanks,

Erik

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Dimitre Novatchev
2003-11-15 13:53:06 UTC
Permalink
Post by y***@yahoo.com.br
Can anyone please tell me how I can escape a single-quote in an XPath expression
such as the one below?
<xsl:value-of select="translate(normalize-space(.), 'x', 'y')"/>
If I use 'x' and 'y' as the search and replace arguments, everything works well. But I
need to search for single-quotes and replace them with backslash + single-quote. In
translate(normalize-space(.), ''', '\'')
translate() can only translate a character into another character or to
nothing. It is not possible using translate() to translate a character into
two or more characters.

For such tasks it is convenient to use the "str-map" template from FXSL.


This transformation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:escape="my:escape"
exclude-result-prefixes="xsl escape"
<xsl:import href="str-map.xsl"/>

<xsl:output method="text"/>
<xsl:variable name="vQ">'</xsl:variable>

<xsl:template match="/">
<xsl:variable name="vEscape" select="document('')/*/escape:*[1]"/>
<xsl:call-template name="str-map">
<xsl:with-param name="pFun" select="$vEscape"/>
<xsl:with-param name="pStr">a'b'c'd</xsl:with-param>
</xsl:call-template>
</xsl:template>

<escape:escape/>
<xsl:template name="excape" match="escape:*">
<xsl:param name="arg1"/>

<xsl:if test="$arg1 = $vQ">\</xsl:if>
<xsl:value-of select="$arg1"/>
</xsl:template>

</xsl:stylesheet>

when performed (on any source.xml -- not used) produces the wanted result:

a\'b\'c\'d


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL





XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-11-15 13:48:11 UTC
Permalink
<xsl:variable name="quot">"</xsl:variable>
<xsl:variable name="apos">'</xsl:variable>
<xsl:value-of select="translate(., $quot, $apos)"/>

Michael Kay
-----Original Message-----
Sent: 15 November 2003 12:55
Subject: [xsl] Escaping quotes in XPath expressions
Hello all,
Can anyone please tell me how I can escape a single-quote in
an XPath expression
such as the one below?
<xsl:value-of select="translate(normalize-space(.), 'x', 'y')"/>
If I use 'x' and 'y' as the search and replace arguments,
everything works well. But I
need to search for single-quotes and replace them with
backslash + single-quote. In
translate(normalize-space(.), ''', '\'')
Except, of course, that I can't use a single-quote
(character) between two single-quotes
(string delimiters). Backslashes don't escape anything, of
course, and using XML
entities (&quot;) inside the search and replace strings won't
work either.
But I just feel there must be a way to do this...
Thanks,
Erik
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
y***@yahoo.com.br
2003-11-17 12:37:58 UTC
Permalink
Post by Dimitre Novatchev
translate() can only translate a character into another character or to
nothing. It is not possible using translate() to translate a character
into two or more characters.
For such tasks it is convenient to use the "str-map" template from
FXSL(...)
------------------------------
Post by Dimitre Novatchev
<xsl:variable name="quot">"</xsl:variable>
<xsl:variable name="apos">'</xsl:variable>
<xsl:value-of select="translate(., $quot, $apos)"/>
------------------------------

First of all, many thanks to Michael and Dimitre for replying to my message.

I had actually thought of using variables, but besides the problem Dimitre pointed out,
I've read that in XSLT 1.1 the value of a variable *must* be contained in a 'select'
attribute, or else you'll be creating a result tree fragment, which in XSLT 1.1 would be
illegal. In other words, if I didn't want to write obsolete code, my variable would have to
look something like this:

<xsl:variable name="apos" select="'"/>

Problem is, in the example above any single-quotes inside the double-quotes would
also be special characters (used to enclose literals), so I'd have to find a way to escape
that darned single-quote. Back to square one.

Is it an inescapable truth that there's no way to escape special characters within an
Xpath string argument? Have I missed something about the creation of variables in
XSLT 1.1? Help! :-O

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-11-17 13:19:01 UTC
Permalink
Post by y***@yahoo.com.br
I've read that in XSLT 1.1 the value of a variable *must* be contained in a 'select'
attribute, or else you'll be creating a result tree fragment,
You mean xslt 1.0 here (there never was (and never will be) an xslt 1.1
just a draft that was never coompleted to a recommendation)

<xsl:variable name="quot">"</xsl:variable>

is legal xslt 1.0 (creating a result tree fragment) and will be legal
XSLT 2 (creating a node sequence). the terminology has changed but
it doesn't affect the code use here.
Post by y***@yahoo.com.br
<xsl:variable name="apos" select="'"/>
If you want to do it using select then you need teh Xpath expression "'"
and to put that expression into an XML attribute you need either

select="&quot;'&quot;"
or
select="'"&apos;"'

as that is, in general how to get a string containing " or ' into an XML
attribute.
Post by y***@yahoo.com.br
Is it an inescapable truth that there's no way to escape special characters within an
Xpath string argument? Have I missed something about the creation of variables in
XSLT 1.1? Help! :-O
this is in the FAQ for this list.

David
--
http://www.dcarlisle.demon.co.uk/matthew

________________________________________________________________________
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-11-17 13:45:12 UTC
Permalink
Post by y***@yahoo.com.br
Post by Michael Kay
<xsl:variable name="quot">"</xsl:variable>
<xsl:variable name="apos">'</xsl:variable>
<xsl:value-of select="translate(., $quot, $apos)"/>
------------------------------
First of all, many thanks to Michael and Dimitre for replying
to my message.
I had actually thought of using variables, but besides the
problem Dimitre pointed out,
I've read that in XSLT 1.1 the value of a variable *must* be
contained in a 'select'
attribute, or else you'll be creating a result tree fragment,
which in XSLT 1.1 would be
illegal.
Firstly, XSLT 1.1 is dead in the water.

Secondly, the above works fine under XSLT 2.0. It's true that you are
creating temporary trees rather than strings, but they are converted to
strings quite happily when used in a context where a string is expected.

But if you prefer, you could write:

<xsl:variable name="quot" select='"'/>
<xsl:variable name="apos" select="'"/>

Dimitre thought you were actually trying to use translate() to replace
one character by several. If that's the case, then he's right, you can't
do it.

Michael Kay


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Dimitre Novatchev
2003-11-17 17:50:45 UTC
Permalink
Post by y***@yahoo.com.br
Post by Dimitre Novatchev
translate() can only translate a character into another character or to
nothing. It is not possible using translate() to translate a character
into two or more characters.
For such tasks it is convenient to use the "str-map" template from
FXSL(...)
------------------------------
Post by Dimitre Novatchev
<xsl:variable name="quot">"</xsl:variable>
<xsl:variable name="apos">'</xsl:variable>
<xsl:value-of select="translate(., $quot, $apos)"/>
------------------------------
First of all, many thanks to Michael and Dimitre for replying to my message.
I had actually thought of using variables, but besides the problem Dimitre pointed out,
I've read that in XSLT 1.1 the value of a variable *must* be contained in a 'select'
attribute, or else you'll be creating a result tree fragment, which in XSLT 1.1 would be
illegal. In other words, if I didn't want to write obsolete code, my variable would have to
This is not "obsolete code" -- you should have tried running it before
publishing such a wrong conclusion.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
y***@yahoo.com.br
2003-11-17 21:00:08 UTC
Permalink
Here's "wrap-up" for anyone following this thread.
Post by Michael Kay
Firstly, XSLT 1.1 is dead in the water.
You mean xslt 1.0 here (there never was (and never will be) an xslt
1.1 just a draft that was never coompleted to a recommendation)
Actually, I did mean XSLT 1.1 — sorry about that! My reference was "Inside XSLT" by
Steven Holzner (2001), but that book is obviously completely outdated by now.

---------------------
Post by Michael Kay
<xsl:variable name="quot" select='"'/>
<xsl:variable name="apos" select="'"/>
If you want to do it using select then you need teh Xpath expression
"'" and to put that expression into an XML attribute you need either
select="&quot;'&quot;"
or
select="'&quot;'"
I tried both solutions but only the second one (David's) seems to work. The processors I
used for the test were IE 6's and Netscape 7.1's build-in processores and PHP's
Sablotron (PHP v. 4.3.4). (Forgive me if Sablotron is not the actual name of the PHP
processor; I get confused.)

---------------------
Post by Michael Kay
Dimitre thought you were actually trying to use translate() to replace one
character by several. If that's the case, then he's right, you can't do
it.
Dimitre was right, but after I found out that 'translate()' wouldn't do what I needed, I
thought I might as well dig into this and learn a little.

A million thanks to Michael, Dimitre and David for spending some of their valuable time
trying to help me. Hopefully other people will also have learned something from this
thread.

Erik

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Dimitre Novatchev
2003-11-17 22:04:49 UTC
Permalink
Post by y***@yahoo.com.br
Hopefully other people will also have learned something from this
thread.
See also:
http://dpawson.co.uk/xsl/sect2/N7150.html#d7559e577


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
y***@yahoo.com.br
2003-11-18 15:42:41 UTC
Permalink
Post by Dimitre Novatchev
Post by y***@yahoo.com.br
Hopefully other people will also have learned something from this
thread.
http://dpawson.co.uk/xsl/sect2/N7150.html#d7559e577
For those who haven't visited the link above, I've found it to be
extremely useful, not just for escaping quotes in XPath expressions
but for information on speacial characters in general.

Thanks a lot, Dimitre! If only I had found that site during my
initial search (which took a good three of hours)...

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-11-18 16:04:30 UTC
Permalink
Post by y***@yahoo.com.br
If only I had found that site during my
initial search (which took a good three of hours)...
If you go to the home page for this list at the url attached to every
message, you'll see a link to that FAQ in the sidebar, and in the list
of links at the top of the main page content.

David
--
http://www.dcarlisle.demon.co.uk/matthew

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