XPath2 in .Net
“What? No XPath2 in .Net? Only v1?”
This is how it starts. At first you can call Microsoft however you want for not implementing XPath2, not even in .Net framework 4. But then you should come together and do it yourself. Actually doing a small workaround, that will enable you to use XPath2 functions in .Net.
First of all see the difference between the XPath functions implemented by Microsoft and the XPath2 standard functions.
Most likely for XSLT transformation in .Net you will use XslCompiledTransform. The workaround is based on adding an extension object.
// creating the XSLT transformation object XslCompiledTransform xslTransform = new XslCompiledTransform(); // loading the stylesheet - see the Load method for all the possible arguments xslTransform.Load(...); // create the transformation arguments object XsltArgumentList xslArg = new XsltArgumentList(); // the extension object needed for the workaround xslArg.AddExtensionObject("urn:xpath2", new XPath2()); // apply the transformation xslTransform.Transform(inputXmlDocument, xslArg, output);
And now we have to define the XPath class
using System.Text.RegularExpressions; public class XPath2 { public int compare(String comparand1, String comparand2) { return comparand1.CompareTo(comparand2); } public String replace(String input, String pattern, String replacement) { return Regex.Replace(input, pattern, replacement); } }
For the sake of example and simplicity I included in here only two example functions, compare
and replace
. But you can implement here all the XPath2 functions that you need, as methods (not static ones) of the class XPath2.
In the XSLT file it is mandatory to have
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xpath2="urn:xpath2">
as the first line. And then using any function will be simple and straightforward:
<xsl:value-of select="xpath2:compare('xpath1', 'xpath2')" />
Of course another way will be to simply use Saxon, an open source implementation for XSLT 2 for both Java and .Net. But if you just need an XPath2 function, it should be simpler what I described above.