I’ve recently added bookmark links to my website for various social networks – these are the links that when clicked allow a visitor to bookmark or promote a page that they like. Implementing these links required writing some XSLT that would produce the correct URL – specifically, I had to pass the URL of the current page as a URL parameter (also known as query strings). This required URL encoding, which isn’t entirely straight forward in XSLT…
What is URL encoding?
URLs can only consist of characters belonging to a character set chosen specifically for URLs. There are approximately 60 characters in this set, of which some are “reserved” – this grants them a special meaning depending on their context within a URL. For example, all but the most trivial of URLs will feature forward slashes to delimit path segments.
To use a reserved character in a way that doesn’t invoke its special meaning, or, for that matter, to use a character from outside the character set, requires the character in question to be URL encoded.
When a character is being encoded it is converted to its corresponding ASCII value, which is then converted into a pair of hexadecimal digits. These digits are then prefixed with a percent sign. For example, a forward slash has ASCII value 47, which is 2F in hexadecimal. A URL encoded forward slash therefore appears as “%2F” within a URL.
Query strings in particular, which are parts of URLs used to pass data between pages, need to be URL encoded if they contain reserved characters. This prevents any confusion over how a character should be interpreted. For example, ampersands are used as delimiters between query strings, therefore ampersands must be URL encoded when intended to be part of a query string itself.
How to URL encode with XSLT
If you’re using XSLT 2 then you should be able to use the “fn:encode-for-uri” function. In most cases you would probably just use it on query strings and then concatenate the result with the URL you are building.
If you’re using XSLT 1 and a Java based XSLT processor then you should be able to “outsource” the URL encoding to Java, e.g:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:url="http://whatever/java/java.net.URLEncoder" version="1.0" exclude-result-prefixes="url">
<xsl:value-of select="url:encode('This is URL encoded')" />
The exact way that you invoke Java may vary depending on your XSLT processor, but I believe the above should work for Saxon. The important part in the above code is the inclusion of the “url” namespace. This allows you to invoke the “encode” function from the java.net.URLEncoder class via “url:encode”.
If you’re not able to use Java to do the heavy lifting for you then you may want to use this URL encoding stylesheet. I use it on my own website and it seems to work well.