XSLT - Replace apostrophe with escaped text in output

21,774

Solution 1

So you have ' in your input, but you need the string   in your output?

In your XSL file, replace ' with ', using this find/replace implementation (unless you are using XSLT 2.0):

<xsl:template name="string-replace-all">
  <xsl:param name="text"/>
  <xsl:param name="replace"/>
  <xsl:param name="by"/>
  <xsl:choose>
    <xsl:when test="contains($text,$replace)">
      <xsl:value-of select="substring-before($text,$replace)"/>
      <xsl:value-of select="$by"/>
      <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="substring-after($text,$replace)"/>
        <xsl:with-param name="replace" select="$replace"/>
        <xsl:with-param name="by" select="$by"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Call it this way:

<loc>
  <xsl:call-template name="string-replace-all">
    <xsl:with-param name="text" select="umbraco.library:NiceUrl($node/@id)"/>
    <xsl:with-param name="replace" select="&apos;"/>
    <xsl:with-param name="by" select="&amp;apos;"/>
  </xsl:call-template>
</loc>

The problem is &apos; is interpreted by XSL as '. &amp;apos; will be interpreted as &apos;.

Solution 2

The simple way to remove unwanted characters from your URL is to change the rules umbraco uses when it generates the NiceUrl.

Edit the config/umbracoSettings.config

add a rule to remove all apostrophes from NiceUrls like so:

<urlReplacing>
    ...
    <char org="'"></char>     <!-- replace ' with nothing -->
    ...
</urlReplacing>

Note: The contents of the "org" attribute is replaced with the contents of the element, here's another example:

<char org="+">plus</char> <!-- replace + with the word plus -->
Share:
21,774
Neil Fenwick
Author by

Neil Fenwick

Updated on October 28, 2020

Comments

  • Neil Fenwick
    Neil Fenwick over 3 years

    I'm writing an XSLT template that need to output a valid xml file for an xml Sitemap.

    <url>
    <loc>
        <xsl:value-of select="umbraco.library:NiceUrl($node/@id)"/>
    </loc>
    <lastmod>
        <xsl:value-of select="concat($node/@updateDate,'+00:00')"/>
    </lastmod>
    </url>
    

    Unfortunately, Url that is output contains an apostrophe - /what's-new.aspx

    I need to escape the ' to &apos; for google Sitemap. Unfortunately every attempt I've tried treats the string '&apos;' as if it was ''' which is invalid - frustrating. XSLT can drive me mad sometimes.

    Any ideas for a technique? (Assume I can find my way around XSLT 1.0 templates and functions)

  • Neil Fenwick
    Neil Fenwick almost 15 years
    Thanks I tried that and also in combination with declaring a variable called $apos with a value of ' and then tried using a replace function to replace $apos with '&apos;' - unfortunately XSLT interprets '&apos;' as ''' which is an unclosed quote again - grrr
  • Neil Fenwick
    Neil Fenwick almost 15 years
    Thanks for the tip. I gave that a try on a local dev box and found a small side-effect. The replacing only applies to nodes that are published after the config change. Any existing nodes with those characters need to be republished - its a big complicated site with lots of links in - would have to add loads of URL rewrite rules :(
  • Myster
    Myster almost 15 years
    you can 'republish entire site' (right click the root node in the tree view) of course any bookmarked urls will be wrong but the internal links should be updated. You MAY have to do a "HARD republish" if that doesn't work
  • East of Nowhere
    East of Nowhere over 11 years
    select="&amp;apos;" give me a syntax error: Unexpected token '&' in the expression. -->&<--apos;
  • Tom McDonald
    Tom McDonald over 7 years
    I get error: String literal was not closed. -->'<--