|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe XSL transformation is a powerful way of visualizing XML. The presence of extension objects makes it even more powerful. However it turns out that extension objects are very limited. They have no way of retrieving the current context of the transformation or the current document. Furthermore their return type is limited to only numbers and strings (returning an Why use context aware XPath functionsA simple but very powerful application of such is the <xsl:variable name='vTest'>123456</xsl:variable>
<xsl:variable name= 'vQuery'>$vTest</xsl:variable>
If you take the value of BackgroundTo read this article you should have good knowledge in C# and the Microsoft's .NET XML parser. How it worksIt looks like Microsoft have had the idea of allowing the user to write context aware functions. Have a look at the 2 classes public virtual IXsltContextFunction ResolveFunction(string prefix,
string name, System.Xml.XPath.XPathResultType[] argTypes){
IXsltContextFunction local0;
string local1;
object local2;
MethodInfo local3;
local0 = null;
if (prefix == String.Empty)
local0 = XsltCompileContext.s_FunctionTable.get_Item(name)
as IXsltContextFunction;
else {
local1 = this.LookupNamespace(prefix);
if (local1 == "urn:schemas-microsoft-com:xslt" && name == "node-set")
local0 = XsltCompileContext.s_FuncNodeSet;
else {
local3 = this.GetExtentionMethod(local1, name, argTypes, local2);
if (local2 == null)
throw new XsltException("Xslt_ScriptInvalidPrefix", prefix);
if (local3 != null)
local0 = new FuncExtension(local2, local3);
}
}
if (local0 == null)
throw new XsltException("Xslt_UnknownXsltFunction", name);
if ((int) argTypes.Length < local0.Minargs ||
local0.Maxargs < (int) argTypes.Length)
throw new XsltException("Xslt_WrongNumberArgs", name,
Convert.ToString((int) argTypes.Length));
return local0;
}
As you can see there are 3 types of functions that the XSLT can resolve:
From the code above, it is visible that the only way of inserting a context aware function is to put it in the static hashtable static Hashtable XslFunctionTable
{
get
{
Assembly xmlAssembly = Assembly.LoadWithPartialName("System.Xml");
Type tXsltCompileContext = xmlAssembly.GetType
("System.Xml.Xsl.XsltCompileContext");
FieldInfo finf = tXsltCompileContext.GetField("s_FunctionTable",
BindingFlags.NonPublic | BindingFlags.Static);
return finf.GetValue(null) as Hashtable;
}
}
Once we have the hash table we can easily add or remove functions from it. The hashtable is initialized in the static constructor of DrawbacksThis is actually a hack. It works fine on .NET framework 1.0 but it may not work in future releases of the framework. I hope Microsoft fixes this problem in future. Also you can add functions only in the root Possible improvementsThe
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||