当前位置:中国站长下载文章中心网页编程.NET编程 → 为XPath自定义函数(因为XPath1.0的函数非常有限)

为XPath自定义函数(因为XPath1.0的函数非常有限)

减小字体 增大字体 作者:不详  来源:不详  发布时间:2006-8-14 8:26:29
     想要一个正则表达式的匹配函数,但是XPath1.0中间没有,
  只好自己扩展一个,在网上搜了一下,有一篇文章不错,
  http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
  该文章定义了一个split,一个replace,不过就是没有match,
  只好在它的基础上,扩展一下
  
  仔细观察一下代码,发现想要扩展一个函数很简单,只要修改这几段就好了:
  
  1:CustomContext.cs
  
  
  // Function to resolve references to my custom functions.
   public override IXsltContextFunction ResolveFunction(string prefix,
   string name, XPathResultType[] ArgTypes)
   {
   XPathRegExExtensionFunction func = null;
   // Create an instance of appropriate extension function class.
   switch (name)
   {
   case "Match":
   // Usage
   // myFunctions:Matches(string source, string Regex_pattern) returns Boolean
   func = new XPathRegExExtensionFunction("Match", 2, 2, new
   XPathResultType[] {XPathResultType.String, XPathResultType.String}
   , XPathResultType.Boolean );
   break;
   case "Split":
   // Usage
   // myFunctions:Split(string source, string Regex_pattern, int n) returns string
   func = new XPathRegExExtensionFunction("Split", 3, 3, new
   XPathResultType[] {XPathResultType.String, XPathResultType.String,
  XPathResultType.Number}, XPathResultType.String);
   break;
   case "Replace":
   // Usage
   // myFunctions:Replace(string source, string Regex_pattern, string replacement_string) returns string
   func = new XPathRegExExtensionFunction("Replace", 3, 3, new
   XPathResultType[] {XPathResultType.String, XPathResultType.String,
  XPathResultType.String}, XPathResultType.String);
   break;
   }
   return func;
   }
  
  
  2: XPathRegExExtensionFunction.cs
  
  
  // This method is invoked at run time to execute the user defined function.
   public object Invoke(XsltContext xsltContext, object[] args,
   XPathNavigator docContext)
   {
   Regex r;
   string str = null;
   // The two custom XPath extension functions
   switch (m_FunctionName)
   {
   case "Match":
   r = new Regex(args[1].ToString());
   MatchCollection m = r.Matches(args[0].ToString());
   if (m.Count == 0)
   {
   return false;
   }
   else
   {
   return true;
   }
   break;
  
   case "Split":
   r = new Regex(args[1].ToString());
   string[] s1 = r.Split(args[0].ToString());
   int n = Convert.ToInt32(args[2]);
   if (s1.Length < n)
   str = "";
   else
   str = s1[n - 1];
   break;
   case "Replace":
   r = new Regex(args[1].ToString());
   string s2 = r.Replace(args[0].ToString(), args[2].ToString());
   str = s2;
   break;
   }
   return (object)str;
   }
  
  
  另外一个文件XPathExtensionVariable.cs其实和函数扩展没有太多的关系,那是设置参数的。
  
  这连个文件修改好了之后,就可以调用了:
  
  
  
  query = navigator.Compile("xdUtil:Match(9,'\\d')");
   CustomContext cntxt = new CustomContext();
   // Add a namespace definition for myFunctions prefix.
   cntxt.AddNamespace("xdUtil", "http://myXPathExtensionFunctions");
   query.SetContext(cntxt);
   Evaluate(query, navigator);
  当然,要是支持XPath2.0 就好了,XPath2.0这些函数都是内置支持的,可惜目前好像还不支持。
  
  全部的代码在这里:
  http://cleo.cnblogs.com/Files/cleo/XPathExtFunction.rar
  
  出处:cleo BLOG
  
  
  
  
    做人要厚道,请注明转自chinazhan中国站长(www.ChinaZhan.com)。