XPath高级用法(冰山一角)

运算符+内置函数

使用XPath选择元素时,使用运算符+内置函数来进行筛选:

.//div[contains(@class,"ec_desc") or contains(@class,"ec_adv_title_desc")]
.//span[@class="ec_site" or @class="ec_adv_site"]

使用c# .net中添加XPath自定义函数

参考:
(http://technet.microsoft.com/zh-cn/magazine/dd567715(VS.100).aspx)
(http://www.cnblogs.com/shenba/archive/2009/12/18/1626898.html)
(http://msdn.microsoft.com/zh-cn/library/ms950806.aspx)

XsltContext,IXsltContextFunction,IXsltContextVariable

        public override IXsltContextFunction ResolveFunction(string prefix,
     string name, XPathResultType[] ArgTypes)
        {
            XPathExtensionFunction func = null;
            // Create an instance of appropriate extension function class.
            switch (name)
            {
                // 匹配正则表达式, XPath1.0没有该方法
                case "IsMatch":
                    func = new XPathExtensionFunction("IsMatch", 2, 2, new
        XPathResultType[] { XPathResultType.String, XPathResultType.String }, XPathResultType.Boolean);
                    break;
                case "Replace":
                    func = new XPathExtensionFunction("Replace", 3, 3, new
        XPathResultType[] { XPathResultType.String, XPathResultType.String, XPathResultType.String }, XPathResultType.String);
                    break;
                // 去除空格
                case "Trim":
                    func = new XPathExtensionFunction("Trim", 1, 1,
                        new XPathResultType[] { XPathResultType.String }, XPathResultType.String);
                    break;
                default:
                    throw new ArgumentException("没有定义" + name + "函数");
            }

            return func;
        }
        // 在运行时调用
        public object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
        {
            // The two custom XPath extension functions
            switch (m_FunctionName)
            {
                case "IsMatch":
                    // 调用正则匹配 参数一为正则表达式
                    return Regex.IsMatch(args[0].ToString(), args[1].ToString());
                case "Replace":
                    // 调用正则匹配 参数一为正则表达式
                    return Regex.Replace(args[0].ToString(), args[1].ToString(),args[2].ToString());
                case "Trim":
                    return docContext.Value.Trim();
                default:
                    throw new ArgumentException("没有定义" + m_FunctionName + "函数");
            }
        }
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            XpathContext xpathContext = new XpathContext();

            var nodes = doc.SelectNodes(@"//a[Replace(string(@href),'^.*2009-10.*$','xxx')='xxx']", xpathContext);
            foreach (XmlNode item in nodes)
            {
                Console.WriteLine(item.Attributes["href"].Value);
            }

注意:自定义函数时,引用属性作为参数时,使用string()函数转换一下

string(@href)

XPath其本质就是用来选择*ML元素的,对于自定义函数,应该是用来给选择元素的过程中,提供一个条件,不选,YESNO,所以本质上函数应该都是布尔型的返回值。即使你定义一个函数返回值不是布尔型,比如string,那么你就必须在XPath表达式中进行比较运算,类似 //span[myfun(str)='result']。否则没有任何意义。

posted @ 2014-08-13 15:21  花生!~~  阅读(1648)  评论(0编辑  收藏  举报