C#中使用XPath示例总结

2021-03-17  本文已影响0人  Sunday_1024

0 xpath简介

用来解析html或xml查找信息的语言。

1 xpath语法

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
例子

以下面的这个xml为例子

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>
谓语
路径表达式 结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
选取未知节点
通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

例子:

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。
选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

2 轴

轴可定义相对于当前节点的节点集。

轴名称 结果
ancestor 选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute 选取当前节点的所有属性。
child 选取当前节点的所有子元素。
descendant 选取当前节点的所有后代元素(子、孙等)。
descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following 选取文档中当前节点的结束标签之后的所有节点。
namespace 选取当前节点的所有命名空间节点。
parent 选取当前节点的父节点。
preceding 选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling 选取当前节点之前的所有同级节点。
self 选取当前节点。
步的语法:

轴名称::节点测试[谓语]

例子:

例子 结果
child::book 选取所有属于当前节点的子元素的 book 节点。
attribute::lang 选取当前节点的 lang 属性。
child::* 选取当前节点的所有子元素。
attribute::* 选取当前节点的所有属性。
child::text() 选取当前节点的所有文本子节点。
child::node() 选取当前节点的所有子节点。
descendant::book 选取当前节点的所有 book 后代。
ancestor::book 选择当前节点的所有 book 先辈。
ancestor-or-self::book 选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)
child::*/child::price 选取当前节点的所有 price 孙节点。

3 一些函数

比如说,想获取网站描述的内容值 <meta name='Description' content='友情链接查询' /> 或<meta name='description' content='友情链接查询' /> ,下面的xpath即可。

//meta[translate(@name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')="DESCRIPTION"]
代码意思为:把name的值a到z转换为大写A到Z,判断是否和目标值"DESCRIPTION"(注意目标值是大写的)相等

4 一个xpath示例(使用HtmlAgilityPack)

                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(@"
<html>
  <head>
    <meta name='content-type' content='text/html; charset=utf-8' />
    <title>友情链接查询 - 站长工具</title>
    <!-- uRj0Ak8VLEPhjWhg3m9z4EjXJwc -->
    <meta name='Keywords' content='友情链接查询' />
    <meta name='Description' content='友情链接查询' />

  </head>
  <body>
    <h1 class='heading'>Top News</h1>
    <p style='font-size: 200%'>World News only on this page</p>
    Ah, and here's some more text, by the way.
    <p>... and this is a parsed fragment ...</p>

    <a href='http://www.cydf.org.cn/' rel='nofollow' target='_blank'>青少年发展基金会</a> 
    <a href='http://www.4399.com/flash/32979.htm' target='_blank'>洛克王国</a> 
    <a href='http://www.4399.com/flash/35538.htm' target='_blank'>奥拉星</a> 
    <a href='http://game.3533.com/game/' target='_blank'>手机游戏</a>
    <a href='http://game.3533.com/tupian/' target='_blank'>手机壁纸</a>
    <a href='http://www.4399.com/' target='_blank'>4399小游戏</a> 
    <a href='http://www.91wan.com/' target='_blank'>91wan游戏</a>

  </body>
</html>

");

                HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//a");//xpath表达式,获取所有链接

                if (nodes == null)
                {
                    txa_new.Text = "===================匹配不到==================";
                    return;
                }

                StringBuilder sb = new StringBuilder();
                sb.AppendLine("获取匹配节点(node)总数:" + nodes.Count);
                sb.AppendLine("*******************我是分隔符*******************");

                HtmlNode node;

                for (int i = 0; i < nodes.Count; i++)
                {
                    node = nodes[i];
                    if (cb_showAttributes.Checked)
                    {
                        var attrList = node.Attributes;
                        foreach (var attr in attrList)
                        {
                            sb.AppendLine("[Attributes]:" + attr.Name + " => " + attr.Value);
                        }
                    }
                    if(cb_InnerHtml.Checked)sb.AppendLine("[InnerHtml]:" + node.InnerHtml);
                    if(cb_InnerText.Checked)sb.AppendLine("[InnerText]:" + node.InnerText);
                    if(cb_OuterHtml.Checked)sb.AppendLine("[OuterHtml]:" + node.OuterHtml);
                    if(cb_XPath.Checked)    sb.AppendLine("[XPath]:"     + node.XPath);
                    sb.AppendLine(string.Format("===================我是分隔符{0}===================",i+1));
                }


                txa_new.Text = sb.ToString();

获取结果:

获取匹配节点(node)总数:7
*******************我是分隔符*******************
[Attributes]:href => http://www.cydf.org.cn/
[Attributes]:rel => nofollow
[Attributes]:target => _blank
[InnerHtml]:青少年发展基金会
[InnerText]:青少年发展基金会
[OuterHtml]:<a href="http://www.cydf.org.cn/" rel="nofollow" target="_blank">青少年发展基金会</a>
[XPath]:/html[1]/body[1]/a[1]
===================我是分隔符1===================
[Attributes]:href => http://www.4399.com/flash/32979.htm
[Attributes]:target => _blank
[InnerHtml]:洛克王国
[InnerText]:洛克王国
[OuterHtml]:<a href="http://www.4399.com/flash/32979.htm" target="_blank">洛克王国</a>
[XPath]:/html[1]/body[1]/a[2]
===================我是分隔符2===================
[Attributes]:href => http://www.4399.com/flash/35538.htm
[Attributes]:target => _blank
[InnerHtml]:奥拉星
[InnerText]:奥拉星
[OuterHtml]:<a href="http://www.4399.com/flash/35538.htm" target="_blank">奥拉星</a>
[XPath]:/html[1]/body[1]/a[3]
===================我是分隔符3===================
[Attributes]:href => http://game.3533.com/game/
[Attributes]:target => _blank
[InnerHtml]:手机游戏
[InnerText]:手机游戏
[OuterHtml]:<a href="http://game.3533.com/game/" target="_blank">手机游戏</a>
[XPath]:/html[1]/body[1]/a[4]
===================我是分隔符4===================
[Attributes]:href => http://game.3533.com/tupian/
[Attributes]:target => _blank
[InnerHtml]:手机壁纸
[InnerText]:手机壁纸
[OuterHtml]:<a href="http://game.3533.com/tupian/" target="_blank">手机壁纸</a>
[XPath]:/html[1]/body[1]/a[5]
===================我是分隔符5===================
[Attributes]:href => http://www.4399.com/
[Attributes]:target => _blank
[InnerHtml]:4399小游戏
[InnerText]:4399小游戏
[OuterHtml]:<a href="http://www.4399.com/" target="_blank">4399小游戏</a>
[XPath]:/html[1]/body[1]/a[6]
===================我是分隔符6===================
[Attributes]:href => http://www.91wan.com/
[Attributes]:target => _blank
[InnerHtml]:91wan游戏
[InnerText]:91wan游戏
[OuterHtml]:<a href="http://www.91wan.com/" target="_blank">91wan游戏</a>
[XPath]:/html[1]/body[1]/a[7]
===================我是分隔符7===================

删除注释内容

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html或xml的code);

            foreach (HtmlNode comment in doc.DocumentNode.SelectNodes("//comment()"))
            {
                //删除注释的html或xml代码
                comment.ParentNode.RemoveChild(comment);
            }
            //获取删除注释后的html或xml代码
            string newHtml = doc.DocumentNode.InnerHtml;

5 注意一点

xpath只能是小写(跟数据大小写无关),否则不能正常匹配你要查的数据。
测试xpath可以使用工具: http://www.1024todo.cn:8000/tool.aspx#/tool/xpath.aspx

上一篇下一篇

猜你喜欢

热点阅读