C#使用Linq to XML进行XPath查询
最近在用到HtmlAgliltyPack进行结点查询时,发现这里选择结点使用的是XPath。所以这里总结一下在C#中使用XPath查询XML的方法。习惯了用Linq,这里也是用的Linq to xml的。
Linq To XML的核心类是XDocument和XElement、XAttribute,需要引用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查询的更多相关文章
- Python通过lxml库遍历xml通过xpath查询(标签,属性名称,属性值,标签对属性)
xml实例: 版本一: <?xml version="1.0" encoding="UTF-8"?><country name="c ...
- 为什么LINQ to XML的性能要优于XmlDocument?
一直很忙,压了很多贴,今天发一篇吧.后面的看心情吧. 今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteN ...
- C#基础知识---Linq操作XML文件
概述 Linq也就是Language Integrated Query的缩写,即语言集成查询,是微软在.Net 3.5中提出的一项新技术. Linq主要包含4个组件---Linq to Objects ...
- linq to xml学习
http://www.cnblogs.com/greatverve/archive/2010/07/09/linq-to-xml-add-delete-update-query.html 记录一下,别 ...
- C#3.0新增功能09 LINQ 基础01 语言集成查询
连载目录 [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...
- C# xml 读xml、写xml、Xpath、Xml to Linq、xml添加节点 xml修改节点
#region XDocument //创建XDocument XDocument xdoc2 = new XDocument(); XElement xel1= new XElement(" ...
- LINQ系列:LINQ to XML查询
1. 读取XML文件 XDocument和XElement类都提供了导入XML文件的Load()方法,可以读取XML文件的内容,并转换为XDocument或XElement类的实例. 示例XML文件: ...
- .NET(C#):使用XPath查询带有命名空间(有xmlns)的XML
原文http://www.cnblogs.com/mgen/archive/2011/05/24/2056025.html 众所周知,XmlDocument可以进行XPath查询,但实际上这里所说的X ...
- hibernate mapping文件中 xmlns会导致linq to xml 查询不到对应的节点
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
随机推荐
- TP5验证码上传阿里云万网虚拟主机后,验证码不显示的解决办法
TP5不显示验证码 清除缓冲区就应该可以了,今天我刚好也遇到了,解决的办法是在vendor/topthink/think-captcha/CaptchaController.php中加上这个ob_cl ...
- vscode前端插件(我的标配)
前言 今天给我的vscode编辑汉化了一下)我也不知道为什么要汉化一下... 但是汉化后 我的vue文件木有高亮了,2333(只好一顿操作 再安装插件 还要去百度找 自己留存) 汉化后 是所有的插件都 ...
- 如何使用git把本地代码上传(更新)到github上
最近用到git和github记录一下 1.下载git并安装 到官网下载并安装就行了 *如果下载失败,或者太慢,可以复制链接到迅雷下载 2.上传 1.在github新建存储库 库名不能是中文 2.在需要 ...
- 剑指offer:数字在排序数组中出现的次数
题目描述: 统计一个数字在排序数组中出现的次数. 思路分析: 1. 直观思路是直接遍历一遍,统计.复杂度也只要O(n). 2. 显然这道题要考察的内容不这么简单,实际上考虑二分的思想来完成.分别二分查 ...
- 范仁义html+css课程---5、列表
范仁义html+css课程---5.列表 一.总结 一句话总结: 学会基本的使用有序列表.无序列表.定义列表,设置样式的话尽量通过css而不是属性 1.无序列表基本形式(实例)? ul标签包裹li标签 ...
- MetaPruning: Meta Learning for Automatic Neural Network Channel Pruning
MetaPruning: Meta Learning for Automatic Neural Network Channel Pruning 2019-08-11 19:48:17 Paper: h ...
- Springboot单元测试Junit深度实践
Springboot单元测试Junit深度实践 前言 单元测试的好处估计大家也都知道了,但是大家可以发现在国内IT公司中真正推行单测的很少很少,一些大厂大部分也只是在核心产品推广单测来保障质量,今天这 ...
- 自己搭建gitlab服务,组员不能上传代码
原因是因为 没有拉分支 直接在master 上开撸代码 ,master 分支 默认是受保护的,具体操作如下
- mysql 5.6配置
简洁版: [client] port = 3306 socket = /weyeedata/mysql/run/mysql.sock [mysqld] innodb_buffer_pool_size ...
- 顶部导航TabBar、TabBarView、DefaultTabController
原文地址:https://www.cnblogs.com/upwgh/p/11369537.html TabBar:Tab页的选项组件,默认为水平排列. TabBarView:Tab页的内容容器,Ta ...