.NET extension functions
The API for integrated .NET extension functions is available via the .NET classes
ExtensionFunctionDefinition and
ExtensionFunctionCall, both
defined in the Saxon.Api
module. Here is a simple example that defines an extension function
to calculate square roots, registers this extension function with the
Processor, and then invokes it from an XPath expression:
public class Sqrt : ExtensionFunctionDefinition {
public override QName FunctionName {
get { return new QName("http://math.com/", "sqrt") };
}
public override int MinimumNumberOfArguments {
get { return 1 };
}
public override int MaximumNumberOfArguments {
get { return 1 };
}
public override XdmSequenceType[] ArgumentTypes {
get { return new XdmSequenceType[] {
new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?')
}
}
}
public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes) {
return new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_DOUBLE), '?');
}
public override bool TrustResultType {
get { return true };
}
public override ExtensionFunctionCall MakeFunctionCall() {
return new SqrtCall();
}
}
public class SqrtCall : ExtensionFunctionCall {
public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context) {
Boolean exists = arguments[0].MoveNext();
if (exists) {
XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
double val = (double)arg.Value;
double sqrt = System.Math.Sqrt(val);
XdmAtomicValue result = new XdmAtomicValue(sqrt);
return (IxdmEnumerator)result.GetEnumerator();
} else {
return EmptyEnumerator.INSTANCE;
}
}
}
Processor proc = new Processor();
proc.RegisterExtensionFunction(new Sqrt());
XPathCompiler xpc = proc.NewXPathCompiler();
xpc.DeclareNamespace("mf", "http://math.com/");
XdmItem result = xpc.EvaluateSingle("mf:sqrt(2)", null);
Console.WriteLine("Square root of 2 is " + result);Full details of the interface are defined in the .NET API documentation.