how to escape single quote in xslt substring function
Solution 1
The general rules for escaping are:
In 1.0:
- if you want the attribute delimiter in a string literal, use the XML
escape form
"
or'
- if you want the string delimiter in a string literal, you're hosed
In 2.0:
- if you want the attribute delimiter in a string literal, use the XML
escape form
"
or'
- if you want the string delimiter in a string literal, double it (for example, 'I can''t')
The use of a variable $quot or $apos as shown by Vitaliy can make the code much clearer.
Solution 2
This should work:
<xsl:variable name="apos">'</xsl:variable>
...
<xsl:value-of select="substring-before(substring-after($datafromxml, concat('DataFromXML:', $apos)), $apos)" />
Solution 3
You could try swapping and " and ' in your xsl:value-of
<xsl:value-of select='substring-before
(substring-after($datafromxml,"DataFromXML:'"), "'")'/>
Alternatively, you could make use of the translate function to remove the pesky apostrophes
<xsl:value-of select='translate
(substring-after($datafromxml,"DataFromXML:"), "'", "")'/>
Not necessarily nicer, but it does remove the need for a variable.
Solution 4
Even in the most complicated case -- the string contains both a quote and an apostrophe -- the number can be extracted without resorting to variables.
Suppose we have this XML document:
<t>' "12345' "</t>
and want to extruct just the number.
In the following transformation we use a single XPath expression to do exactly that:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()">
<xsl:value-of select=
'substring-after(.,"'")
'/>
==============
<xsl:value-of select=
'substring-before(
substring-after(substring-after(.,"'"), '"'),
"'"
)
'/>
</xsl:template>
</xsl:stylesheet>
The result is:
"12345' "
==============
12345
Do note: I am intentionally having two XPath expressions -- the purpose of the first one is to make it simpler to understand what is expressed in the second XPath expression. Leaving just the last xsl:value-of
in the template body produces exactly the wanted result:
12345
Solution 5
Just a note to my future self (or anyone else) who would benefit from a reminder of the exact syntax that worked for me.
Declare this variable
<xsl:variable name="apos" select='"'"'/>
And use it in a condition like this
<xsl:if test="$value = concat('G-2', $apos, 'd')">89594</xsl:if>
Related videos on Youtube
Comments
-
buttowski over 4 years
I tried to substring data with single quote in XSLT:
String : DataFromXML:'12345'
expected Result:
12345
<xsl:value-of select="substring-after('$datafromxml','DataFromXML:')"/>
Result:
'12345'
i tried below code
<xsl:value-of select="substring-after('$datafromxml','DataFromXML:'')"/> <xsl:value-of select="substring-after('$datafromxml','DataFromXML:'')"/> <xsl:value-of select="substring-after('$datafromxml','DataFromXML:'')"/>
Error:
String literal was not closed 'DataFromXML:'--->'<---
-
Vitaliy almost 12 yearsDid you try double quotes "''"?
-
buttowski almost 12 yearsYes i tried it am getting compilation error
-
Dimitre Novatchev almost 12 years@prabhu, It is possible to extract the number with a single XPath 1.0 expression even in the most complicated case when the string contains both quotes and apostrophes -- not using any variable at all.
-
-
Vitaliy almost 12 yearsNot sure about XPath 1.0 rules - probably it could also be a simpler solution without special variable
-
Dimitre Novatchev almost 12 yearsMichael, It is actually possible to extract the number with a single XPath 1.0 expression even in the most complicated case when the string contains both quotes and apostrophes -- not using any variable at all.
-
Michael Kay almost 12 yearsPossible, yes, but only by making such heavy use of entity references that the code becomes totally unreadable. And why are variables so bad anyway? - a good processor will inline them.
-
Dimitre Novatchev almost 12 yearsI don't have anything against using variables -- just addressed your statement that "if you want the string delimiter in a string literal, you're hosed" . Sorry for trying to be precise.
-
Peter Wilson about 3 yearsThis is an excellent answer, thanks Nick.
-
Peter Wilson about 3 years(I can't believe I ended up here a few weeks later looking for the same answer, and thinking, "I should mark this answer as correct", only to find out I already did : )