首页 > 开发 > 综合 > 正文

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

2024-07-21 02:29:20
字体:
来源:转载
供稿:网友

想要一个正则表达式的匹配函数,但是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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表