Recently I had to implement an XSLT transformation for a project here. It didn’t seem too complicated at first, since XSLT is not an alien technology – actually, it is pretty simple to use / develop with.
The problem was that, in this particular scenario, we needed namespaces whose URIs were generated dynamically, on pre-defined prefixes. The first idea that comes to mind is to write something like this:
<xsl:attribute name="xmlns:ns"> <xsl:value-of select="$dynamicURI"/> </xsl:attribute>
BUT… you can’t do this. Namespaces can’t be declared as normal attributes; the command above is illegal and won’t be processed by your XLST processor – you will probably get an XSLT compilation error.
If you google this problem for a while (which I did) you will find a few workarounds to make dynamic namespaces work. They basically involve creating dummy elements and copying them around. I tried using such approach for some time, but it started to consume too much time to work, and the resulting XLST code was getting really ugly – which also means that I was getting upset with the problem and its solution.
So I decided to look for a better way, and I found out that you could do this:
<xsl:namespace name="ns" select="$dynamicURI"/>
Amazing! Easy! Beautiful! And it doesn’t work with the standard XSLT processor that comes with Java – even Java 6, which I am using. The problem is that this command is specific to XSLT 2.0, which doesn’t seem to be supported by the default XSLT processor that comes bundled with the JDK distribution.
Although I was trying to avoid using external libraries, I had to do it this time. I added Saxon to the project and added this simple line in the code before calling the transformation:
System.setProperty( "javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
Of course, there are other, more maintainable, ways to change this property, but you get the idea. Now I have my nice XLST with dynamic namespaces working, in a nice, simple and readable fashion =D