为XPath自定义函数(因为XPath1.0的函数非常有限)[附源代码下载] 无为而为

想要一个正则表达式的匹配函数,但是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"22new
        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"33new
        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"33new
        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这些函数都是内置支持的,可惜目前好像还不支持。

全部的代码在这里:
/Files/cleo/XPathExtFunction.rar

原文地址:https://www.cnblogs.com/cleo/p/365822.html