how to escape single quote in xslt substring function

53,123

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:&apos;"), "&apos;")'/> 

Alternatively, you could make use of the translate function to remove the pesky apostrophes

 <xsl:value-of select='translate
    (substring-after($datafromxml,"DataFromXML:"), "&apos;", "")'/> 

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(.,"&apos;")
     '/>
==============  
     <xsl:value-of select=
     'substring-before(
       substring-after(substring-after(.,"&apos;"), &apos;&quot;&apos;),
       "&apos;"
                       )
     '/>
 </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='"&apos;"'/>

And use it in a condition like this

<xsl:if test="$value = concat('G-2', $apos, 'd')">89594</xsl:if>
Share:
53,123

Related videos on Youtube

buttowski
Author by

buttowski

Java Developer

Updated on February 06, 2020

Comments

  • buttowski
    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:&#39;')"/>
    
    <xsl:value-of select="substring-after('$datafromxml','DataFromXML:&apos;')"/>
    
    <xsl:value-of select="substring-after('$datafromxml','DataFromXML:'')"/>
    

    Error:

    String literal was not closed 'DataFromXML:'--->'<---
    
    • Vitaliy
      Vitaliy almost 12 years
      Did you try double quotes "''"?
    • buttowski
      buttowski almost 12 years
      Yes i tried it am getting compilation error
    • Dimitre Novatchev
      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
    Vitaliy almost 12 years
    Not sure about XPath 1.0 rules - probably it could also be a simpler solution without special variable
  • Dimitre Novatchev
    Dimitre Novatchev almost 12 years
    Michael, 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
    Michael Kay almost 12 years
    Possible, 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
    Dimitre Novatchev almost 12 years
    I 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
    Peter Wilson about 3 years
    This is an excellent answer, thanks Nick.
  • Peter Wilson
    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 : )