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

想要一个正则表达式的匹配函数,但是XPath1.0中间没有,
只好自己扩展一个,在网上搜了一下,有一篇文章不错,
http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
该文章定义了一个split,一个replace,不过就是没有match,
只好在它的基础上,扩展一下

仔细观察一下代码,发现想要扩展一个函数很简单,只要修改这几段就好了:

1:CustomContext.cs

None.gif //  Function to resolve references to my custom functions.
None.gif
         public   override  IXsltContextFunction ResolveFunction( string  prefix,
None.gif     
string  name, XPathResultType[] ArgTypes)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            XPathRegExExtensionFunction func 
= null;
InBlock.gif            
// Create an instance of appropriate extension function class.
InBlock.gif
            switch (name)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case "Match":
InBlock.gif                    
// Usage 
InBlock.gif                    
// myFunctions:Matches(string source, string Regex_pattern) returns Boolean
InBlock.gif
                    func = new XPathRegExExtensionFunction("Match"22new
ExpandedSubBlockStart.gifContractedSubBlock.gif        XPathResultType[] 
dot.gif{XPathResultType.String, XPathResultType.String}
InBlock.gif        , XPathResultType.Boolean );
InBlock.gif                    
break;
InBlock.gif                
case "Split":
InBlock.gif                    
// Usage 
InBlock.gif                    
// myFunctions:Split(string source, string Regex_pattern, int n) returns string
InBlock.gif
                    func = new XPathRegExExtensionFunction("Split"33new
ExpandedSubBlockStart.gifContractedSubBlock.gif        XPathResultType[] 
dot.gif{XPathResultType.String, XPathResultType.String, 
ExpandedSubBlockEnd.gifXPathResultType.Number}
, XPathResultType.String);
InBlock.gif                    
break;
InBlock.gif                
case "Replace":
InBlock.gif                    
// Usage
InBlock.gif                    
// myFunctions:Replace(string source, string Regex_pattern, string replacement_string) returns string
InBlock.gif
                    func = new XPathRegExExtensionFunction("Replace"33new
ExpandedSubBlockStart.gifContractedSubBlock.gif        XPathResultType[] 
dot.gif{XPathResultType.String, XPathResultType.String, 
ExpandedSubBlockEnd.gifXPathResultType.String}
, XPathResultType.String);
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return func;
ExpandedBlockEnd.gif        }

 

2: XPathRegExExtensionFunction.cs

None.gif //  This method is invoked at run time to execute the user defined function.
None.gif
         public   object  Invoke(XsltContext xsltContext,  object [] args,
None.gif     XPathNavigator docContext)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            Regex r;
InBlock.gif            
string str = null;
InBlock.gif            
// The two custom XPath extension functions
InBlock.gif
            switch (m_FunctionName)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case "Match":
InBlock.gif                    r 
= new Regex(args[1].ToString());
InBlock.gif                    MatchCollection m 
= r.Matches(args[0].ToString());
InBlock.gif                    
if (m.Count == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
return false;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
return true;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
break;
InBlock.gif
InBlock.gif                
case "Split":
InBlock.gif                    r 
= new Regex(args[1].ToString());
InBlock.gif                    
string[] s1 = r.Split(args[0].ToString());
InBlock.gif                    
int n = Convert.ToInt32(args[2]);
InBlock.gif                    
if (s1.Length < n)
InBlock.gif                        str 
= "";
InBlock.gif                    
else
InBlock.gif                        str 
= s1[n - 1];
InBlock.gif                    
break;
InBlock.gif                
case "Replace":
InBlock.gif                    r 
= new Regex(args[1].ToString());
InBlock.gif                    
string s2 = r.Replace(args[0].ToString(), args[2].ToString());
InBlock.gif                    str 
= s2;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return (object)str;
ExpandedBlockEnd.gif        }

 

另外一个文件XPathExtensionVariable.cs其实和函数扩展没有太多的关系,那是设置参数的。

这连个文件修改好了之后,就可以调用了:

None.gif query  =  navigator.Compile( " xdUtil:Match(9,'\\d') " );
None.gif            CustomContext cntxt 
=   new  CustomContext();
None.gif            
//  Add a namespace definition for myFunctions prefix.
None.gif
            cntxt.AddNamespace( " xdUtil " " http://myXPathExtensionFunctions " );
None.gif            query.SetContext(cntxt);
None.gif            Evaluate(query, navigator);

当然,要是支持XPath2.0 就好了,XPath2.0这些函数都是内置支持的,可惜目前好像还不支持。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值