最近在用到HtmlAgliltyPack进行结点查询时,发现这里选择结点使用的是XPath。所以这里总结一下在C#中使用XPath查询XML的方法。习惯了用Linq,这里也是用的Linq to xml的。

Linq To XML的核心类是XDocumentXElementXAttribute,需要引用using System.Xml.Linq命名空间。

这三个类简单理解为:

XDocument:打开的整个XML文档

XElement:节点元素

XAttribute:属性

下面简单介绍一下使用

如有以下XML文件

 <?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<title>测试XML</title>
</head>
<body>
<div class="card-container">
<div class="item-title">
<h3 class="item-shop-name">汪家羊肉馆</h3>
</div>
<div class="item-comment">
<span class="price1">¥/人</span>
<span class="price2">¥/人</span>
<span class="price3"></span>
<span class="price4"></span>
</div>
</div>
</body>
</html>

打开XML文件

 XDocument doc = XDocument.Load("demo.xml");

获取根节点(html节点 返回XElement类型)

var root = doc.Root;

获取第一个子节点(返回XElement类型)

 var firstNode = root.FirstNode;

获取全部子节点(返回IEnumerable<XNode>)

 var allChildNode = root.Nodes();

获取指定名称的第一个子节点(返回XElement类型)

 var headNode = root.Element("head");

获取指定名称的全部子节点(返回IEnumerable<XElement>)

var allNamedNode = root.Elements("head");

获取节点指定名称的属性(<div class="card-container"> )

 var attribute = root.Element("body").Element("div").Attribute("class");

获取节点的全部属性

  var allAttributes = root.Attributes();

使用XPath查询(需要引用using System.Xml.XPath命名空间)

 var xpathQeury = root.XPathSelectElement("body/div");

获取节点的名称和值

   //获取结点的名称
var nodeName = root.Name;
//获取节点的值
var nodeValue = root.Value;

保存XML

 doc.Save("demo.xml");

Linq查询(获取<span class="price2">¥12/人</span>节点下的值)

这里仅做示例,返回返回IEnumerable<XElement>类型的都可以进行Linq查询

不使用XPath

 var queryResult = root.Element("body").Element("div").Elements("div").ElementAt().Elements("span").Where(x=>x.Attribute("class") != null && x.Attribute("class").Value == "price2").FirstOrDefault();
if(queryResult != null)
Console.WriteLine(queryResult.Value);

使用XPath

 var xpathQueryResult = root.XPathSelectElements("body/div/div[2]/span").Where(x => x.Attribute("class") != null && x.Attribute("class").Value == "price2").FirstOrDefault();
if(xpathQueryResult != null)
Console.WriteLine(xpathQueryResult.Value);

输出结果都为下

下面开始介绍XPath

XPath 是 XML 文档中查找信息的语言,使用XPath可以对XML的元素进行查找。

这里重着介绍一下XPath语法

/    从根节点开始选择

 var xpathRoot = doc.XPathSelectElement("/html");
var xpathRoot2 = doc.XPathSelectElement("html");

运行结果

//   获取文档中所有指定的结点,不管它的位置

如要获取xml文档中所有的span节点

             //以下获取的结果都是一样的
//尽管位置不一样,但查询结果是一样的
var body = root.Element("body").Element("div").Elements("div").ElementAt();
var allDivNodeInBody = body.XPathSelectElements("//div");
var allDivNodeInDoc = doc.XPathSelectElements("//div");
Console.WriteLine(allDivNodeInBody.Count());
Console.WriteLine(allDivNodeInDoc.Count());

运行结果

.   当前节点

  var currentNode = root.XPathSelectElement(".");
         

运行结果

..  当前节点的父节点

 var parentNode = root.Element("body").XPathSelectElement("..");

运行结果

@  选取属性

这个操作在Linq to xml里不支持,会产生一个"XPath 表达式的计算结果为意外类型 System.Xml.Linq.XAttribute。"异常

通配查询

*     全部节点

@*  全部属性(不支持)

谓词查询

选择第一个查询结果,如<span class="price1">¥62/人</span>

//span[1]
 var firstSpanNode = doc.XPathSelectElement("//span[1]");

运行结果

选择最后一个查询结果,如最后一个<span class="price4">12</span>

//span[last()]
  var lastDivNode = doc.XPathSelectElement("//span[last()]");
Console.WriteLine(lastDivNode.Attribute("class").Value);

运行结果

选择带有属性class的div节点

//div[@class]
 var nodeWithClassAttribute = doc.XPathSelectElements("//div[@class]");
foreach (var item in nodeWithClassAttribute)
{
Console.WriteLine("====================");
Console.WriteLine(item);
}

运行结果

选择带有属性class,且值为item-title的div节点

//div[@class='item-title']
  var nodeWithClassValueAttribute = doc.XPathSelectElements("//div[@class='item-title']");
foreach (var item in nodeWithClassValueAttribute)
{
Console.WriteLine(item);
}

运行结果

简单的选择计算

获取倒数第二个div节点

//div[last()-1]
 var nextToLastDivNode = doc.XPathSelectElement("//div[last()-1]");

运行结果

获取值大于10的span节点

//span[text()>10]
 var greaterThanTenSpan = doc.XPathSelectElements("//span[text()>10]");

运行结果:

获取值加10等于22的span节点

//span[text()+10=22]
 var plusTenSpan = doc.XPathSelectElements("//span[text()+10=22]");

运行结果:

常用运行符如下

+               加

-                减

*               乘

div           除

=              等于

!=             不等于

>              大于

<              小于

>=           大于等于

<=            小于等于

or            或

and          与

组合查询

如查询值等于12或等于2的span节点

//span[text()=2]|//span[text()=12]
  var combineQuery = doc.XPathSelectElements("//span[text()=2]|//span[text()=12]");
foreach (var item in combineQuery)
{
Console.WriteLine(item.Value);
}

运行结果

示例代码

参考:

https://www.w3.org/TR/2017/REC-xpath-31-20170321/

https://www.w3school.com.cn/xpath/index.asp

C#使用Linq to XML进行XPath查询的更多相关文章

  1. Python通过lxml库遍历xml通过xpath查询(标签,属性名称,属性值,标签对属性)

    xml实例: 版本一: <?xml version="1.0" encoding="UTF-8"?><country name="c ...

  2. 为什么LINQ to XML的性能要优于XmlDocument?

    一直很忙,压了很多贴,今天发一篇吧.后面的看心情吧. 今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteN ...

  3. C#基础知识---Linq操作XML文件

    概述 Linq也就是Language Integrated Query的缩写,即语言集成查询,是微软在.Net 3.5中提出的一项新技术. Linq主要包含4个组件---Linq to Objects ...

  4. linq to xml学习

    http://www.cnblogs.com/greatverve/archive/2010/07/09/linq-to-xml-add-delete-update-query.html 记录一下,别 ...

  5. C#3.0新增功能09 LINQ 基础01 语言集成查询

    连载目录    [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...

  6. C# xml 读xml、写xml、Xpath、Xml to Linq、xml添加节点 xml修改节点

    #region XDocument //创建XDocument XDocument xdoc2 = new XDocument(); XElement xel1= new XElement(" ...

  7. LINQ系列:LINQ to XML查询

    1. 读取XML文件 XDocument和XElement类都提供了导入XML文件的Load()方法,可以读取XML文件的内容,并转换为XDocument或XElement类的实例. 示例XML文件: ...

  8. .NET(C#):使用XPath查询带有命名空间(有xmlns)的XML

    原文http://www.cnblogs.com/mgen/archive/2011/05/24/2056025.html 众所周知,XmlDocument可以进行XPath查询,但实际上这里所说的X ...

  9. hibernate mapping文件中 xmlns会导致linq to xml 查询不到对应的节点

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

随机推荐

  1. dropbox icloud and nustore

    dropbox icloud and nustore 这里只是写一下自己的感受. 曾经搜索无数遍, 想着用哪个比较好, 想来比较一下, 还不如自己直接用用看吧. 于是同时用了很久的 dropbx 和 ...

  2. mysql开放远程连接

    1.检查端口是否被监听,没有的话请启动mysql. netstat -atnp | grep 3306 2.检查用户是否具备远程连接,即host字段值不是 % mysql -uroot -p你的密码 ...

  3. 2019SDN第7次上机作业

    2019SDN第7次上机作业 1.作业要求: 作业博客链接:https://edu.cnblogs.com/campus/fzu/fzusdn2019/homework/10165 2.具体操作步骤与 ...

  4. 解决iis内存占用过大的问题--ZT

    解决iis内存占用过大的问题 在IIS6下,经常出现w3wp的内存占用不能及时释放,从而导致服务器响应速度很慢. 今天研究了一下,可以做以下配置: 1.在IIS中对每个网站进行单独的应用程序池配置.即 ...

  5. [转]vscode 插件推荐 - 献给所有前端工程师(2019.8.7更新)

    原文地址:https://segmentfault.com/a/1190000006697219 VScode现在已经越来越完善.性能远超Atom和webstorm,你有什么理由不用它?在这里,我会给 ...

  6. redis的相关原理

    一.AOF 二.RDB 三.哨兵

  7. 查询、下载GWAS目录数据的R包(gwasrapidd)

    目前GWAS方向发了很多文献,但是并没有一个很完善的R包对这些文献的数据进行汇总. 接下来推荐的这个是最新发表的GWAS数据汇总R包​.看了一下功能齐全,但是数据不是收录的很齐全​. 下面具体讲一下. ...

  8. jmap使用

    今天写的服务在处理大文件是出现Java heap space错误,因此结识了jmap jmap是JDK自带的一个工具,可以做jvm性能调优 可以生成dump文件,查询finalize执行队列.Java ...

  9. SQL Server跨服务器操作数据库

    今天给大家来分享一下跨服务器操作数据库,还是以SQL Server的管理工具(SSMS)为平台进行操作. 什么是跨服务器操作? 跨服务器操作就是可以在本地连接到远程服务器上的数据库,可以在对方的数据库 ...

  10. swoole实战1-初识swoole

    原文地址:https://www.jianshu.com/p/008d5702d01f 安装swoole 以mac操作系统为例,如果你是mac新手,推荐阅读 程序员如何优雅使用mac 环境要求:php ...