XPath <第四篇>
.Net框架下的System.Xml.XPath命名空间提供了一系列的类,允许你应用XPath数据模式查询和展示XML文档数据。
一、XPath介绍
XPath有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释、根节点。
二、XPath语法
XPath使用路径表达式来选取XML文档中的节点或节点集。
1、常用的路径表达式:
表达式 | 解释 |
nodename | 选取节点下的所有子节点 |
/ | 选取根节点 |
// | 选取文档中所有符合条件的节点,不管该节点位于何处 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
先贴一个XML文档,以此作为示例的试验文档:
<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
<book>
<title lang="en">三国演义</title>
<author>罗贯中</author>
<year>2005</year>
<price>38.5</price>
</book>
<book>
<title lang="eng">西游记</title>
<author>吴承恩</author>
<year>2004</year>
<price>37.5</price>
</book>
</bookstore>
示例代码:
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument(); //创建文档
doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml"); //加载xml文件 XmlNode node1 = doc.SelectSingleNode("/"); //选中根节点
Console.WriteLine(node1.LocalName); //输出#document XmlNode node2 = doc.SelectSingleNode("bookstore"); //选中bookstore元素
Console.WriteLine(node2.Name); //输出 bookstore XmlNode node3 = doc.SelectSingleNode("/bookstore"); //选中根节点下的bookstore元素
Console.WriteLine(node3.Name); //输出 bookstore XmlNodeList nodelist1 = doc.SelectNodes("//id"); //选中所有符合条件的id元素,不管它的位置如何
foreach (XmlNode node in nodelist1)
{
Console.WriteLine(node.InnerText); //输出 1 2
} XmlNodeList nodelist2 = doc.SelectNodes("bookstore/book/title"); //读取bookstore下的所有book元素下的所有title元素
foreach (XmlNode node in nodelist2)
{
Console.WriteLine(node.InnerText); //输出 三国演义 西游记
} XmlNode node4 = doc.SelectSingleNode("/bookstore/book[1]/title[1]/."); //获取第一个title的当前节点
Console.WriteLine(node4.Name); //输出title XmlNode node5 = doc.SelectSingleNode("/bookstore/book[1]/title[1]/.."); //获取第一个title的父节点
Console.WriteLine(node5.Name); //输出book Console.ReadKey();
}
2、通配符
通配符 | 说明 |
* | 匹配任意的节点元素 |
@* | 匹配任意的节点属性 |
node() | 匹配任意种类的节点 |
text() | 匹配节点的文本内容 |
示例代码:
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument(); //创建文档
doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml"); //加载xml文件 XmlNodeList nodelist1 = doc.SelectNodes("/bookstore/*"); //匹配bookstore下的直接子元素
foreach (XmlNode node in nodelist1)
{
Console.WriteLine(node.Name); //输出 book book 两个book才是直接子元素
} XmlNodeList nodelist2 = doc.SelectNodes("//title[@*]"); //匹配所有含有任意属性的title元素
foreach (XmlNode node in nodelist2)
{
Console.WriteLine(node.Name); //输出 title title 两个title含有属性
} XmlNodeList nodelist3 = doc.SelectNodes("//*"); //匹配所有含有任意属性的title元素
foreach (XmlNode node in nodelist3)
{
Console.WriteLine(node.Name); //输出 所有的元素名 从上至下
} XmlNodeList nodelist4 = doc.SelectNodes("//title|//author"); //匹配所有的title和author元素
foreach (XmlNode node in nodelist4)
{
Console.WriteLine(node.InnerText); //输出 三国演义 罗贯中 西游记 吴承恩
} Console.ReadKey();
}
3、轴
XPath轴可定义相对于当前节点的节点集:
轴名称 | 结果 |
ancestor | 选取当前节点的所有先辈(父,祖父等)不包括自己 |
ancestor-or-self | 选取当前节点的所有先辈,以及自己 |
attribute | 选取当前节点的所有属性 |
child | 选取当前节点的所有子元素 |
descendant | 选取当前节点的所有后代元素(子、孙等)不包括自己 |
descendant-or-self | 选取当前节点的所有后代元素,以及自己 |
following | 选取文档中当前节点的结束标签之后的所有节点 |
namespace | 选取当前节点的所有命名空间节点 |
parent | 选取当前节点的父节点 |
preceding | 选取文档中当前节点的开始标签之前的所有节点 |
preceding-sibling | 选取当前节点之前的所有统计节点 |
self | 选取当前节点 |
与轴有关的两个重要概念:
- 位置;
- 步;
位置路径可以是绝对的,也可以是相对的。
绝对路径表达式:
/step/step/...
相对路径表达式:
step/step/...
而步的定义包括:
- 轴:定义所选节点与当前节点之间的树关系;
- 节点测试:识别某个轴内部的节点;
- 另个或者多个谓词:更深入地提炼所选的节点集。
步的语法:
轴名称::节点测试[谓词]
代码示例:
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument(); //创建文档
doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml"); //加载xml文件 XmlNode node1 = doc.SelectSingleNode("/bookstore/book[1]"); XmlNode node2 = node1.SelectSingleNode("ancestor::*"); //选取当前节点的祖先节点,选择单个(SelectSingleNode)就是直接父元素
Console.WriteLine(node2.Name); //输出 bookstore XmlNodeList nodelist1 = node1.SelectNodes("ancestor-or-self::*"); //选取当前节点的所有先辈元素
foreach (XmlNode node in nodelist1)
{
Console.WriteLine(node.Name); //输出 bookstore book book是self bookstore是ancestor
} XmlNode node3 = node1.SelectSingleNode("child::title"); //选取当前节点的子元素叫title的节点
Console.WriteLine(node3.InnerText); //输出 三国演义 XmlNodeList nodelist2 = node1.SelectNodes("descendant::*");
foreach (XmlNode node in nodelist2)
{
Console.WriteLine(node.Name); //输出 id title author year price
} XmlNodeList nodelist3 = node1.SelectNodes("descendant-or-self::*"); //获取所有的子节点以及自身
foreach (XmlNode node in nodelist3)
{
Console.WriteLine(node.Name); //输出 book id title author year price 其中book是self
} XmlNodeList nodelist4 = node1.SelectNodes("following::*"); //获取第一个book标签结束后的所有节点
foreach (XmlNode node in nodelist4)
{
Console.WriteLine(node.Name); //输出 book id title author year price
} XmlNode node4 = node1.SelectSingleNode("parent::*"); //获取当前的节点的父节点
Console.WriteLine(node4.Name); //输出 bookstore Console.WriteLine("----------------"); XmlNode node5 = doc.SelectSingleNode("/bookstore/book[2]/title[1]"); //选取第二个book的第一个title节点
XmlNodeList nodelist5 = node5.SelectNodes("preceding::*"); //获取当前节点(第二个book的第一个title)开始之前的所有节点
foreach (XmlNode node in nodelist5)
{
Console.WriteLine(node.Name); //输出 book id title author year price id
} XmlNodeList nodelist6 = node5.SelectNodes("preceding-sibling::*"); //获取当前节点(第一个title)开始之前的所有同级别节点
foreach (XmlNode node in nodelist6)
{
Console.WriteLine(node.Name); //输出 id
} XmlNode node7 = node5.SelectSingleNode("self::*");
Console.WriteLine(node7.Name); //输出 title Console.ReadKey();
}
4、XPath运算符
运算符 | 说明 |
| | 计算两个节点集 |
+ | 加法 |
- | 减法 |
* | 乘法 |
div | 除法 |
= | 等于 |
!= | 不等于 |
< | 小于 |
<= | 小于或等于 |
>= | 大于或等于 |
> | 大于 |
or | 或 |
and | 与 |
mod | 计算除法的余数 |
5、特殊字符
特殊字符 | 说明 |
/ | 此路径运算符出现在模式的开头时,表示应从根节点选择 |
// | 从当前节点开始递归下降,此路径运算符出现在模式开头时表示应从节点递归下降 |
. | 当前上下文 |
.. | 当前上下文节点父节 |
* | 通配符;选择所有元素节点和元素名无关(不包括文本、注释、指令等节点,如果也要包含这些节点请用node()函数) |
@ | 属性的前缀 |
@* | 所有的属性,与名称无关 |
: | 命名空间分隔符;将命名空间前缀与元素名分隔 |
() | 括号运算符(优先级最高),强制运算优先级 |
[] | 应用筛选模式(即谓词,包括"过滤表达式"和"轴"(向前/向后)) |
[] | 下标运算符;用于在集合中编制索引 |
6、XPath函数
XPath与XSLT、XQuery等共享函数库,函数库提供了功能丰富的各种内置函数。
(1)存取函数
名称 说明
fn:node-name(node) 返回参数节点的节点名称
fn:nilled(node) 返回是否拒绝参数节点的布尔值
fn:data(item.item,...) 接受项目序列,并返回原子序列
fn:base-uri() fn:base-uri(node)返回当前节点的base-uri属性的值
fn:document-uri(node) 返回指定节点的document-uri属性的值
(2)错误和跟踪函数
名称 说明
fn:error()
fn:error(error)
fn:error(error,description)
fn:error(error,description,error-object)
fn:trace(value,label) 用于对查询进行debug
(3)有关数值的函数
名称 说明
fn:number(arg) 返回参数的数值
fn:abs(num) 返回参数的绝对值
fn:ceiling(num) 返回大于num参数的最小整数
fn:floor(num) 返回不大于num参数的最大整数
fn:round(num) 把num参数舍入为最接近的整数
fn:round-half-to-even() 不明白
(4)有关字符串的函数
名称 说明
fn:string(arg) 返回参数的字符串值。参数可以使数字、逻辑值或节点集
fn:codepoints-to-string(int,int...) 根据代码点序列返回字符串
fn:string-to-codepoints(string) 根据字符串返回代码点序列
fn:codepoint-equal(comp1,comp2) 根据Unicode代码点对照,如果comp1的值等于comp2的值则返回True
fn:compare(comp1,comp2) 如果comp1小于comp2,则返回-1.相等返回0,如果comp1>comp2则返回1。
fn:concat(string,string...) 返回字符串的拼接
fn:string-join((string,string,...),sep) 使用sep参数作为分隔符,来返回string参数拼接后的字符串
fn:substring(string,start,len) 返回从start位置开始的指定长度的子字符串。第一个字符的下标是1。如果省略len参数,则返回从位置start到字符串末尾的 子字符串。
fn:string-length(string) 返回指定字符串的长度,如果没有string参数,则返回当前节点的字符串的值的长度。
fn:normalize-space(string) 删除指定字符串的开头和结尾的空白,并把内部的所有空白序列替换为一个然后返回结果。
fn:normalize-unicode() 执行Unicode规格化
fn:upper-case(string) 把string参数转换为大写
fn:lower-case(string) 把string参数转换为小写
fn:translate(string1,string2,string3) 把string1中的string2替换为string3
fn:escape-uri(stringURI,esc-res) url编码
fn:contains(string1,string2) 如果string1包含string2则返回true,否则返回false
fn:starts-with(string1,string2) 如果string1以string2开始,则返回true,否则返回false
fn:ends-width(string1,string2) 如果string1以string2结尾,则返回true,否则返回false
fn:substring-before(string1,string2) 返回string2在string1中出现之前的子字符串
fn:substring-after(string1,string2) 返回string2在string1中出现之后的子字符串
fn:matches(string,pattern) 如果string参数匹配指定的模式,则返回true,否则返回false
fn:replace(string,pattern,replace) 把指定的模式替换为replace参数,并返回结果
fn:tokenize(string,pattern) pattern匹配到的字符进行分割,并将分割后的结果返回
(5)上下文函数
名称 说明
fn:position() 返回当前正在被处理的节点的index位置
fn:last() 返回在被处理的节点列表中的项目数目
fn:current-dateTime() 返回当前的dateTime(带有时区)
fn:current-date() 返回当前的日期(带有时区)
fn:current-time() 返回当前的时间(带有时区)
fn:implicit-timezone() 返回隐式时区的值
fn:default-collation() 返回默认对照的值
fn:static-base-uti() 返回base-uri的值
(6)关于节点的函数
名称 说明
fn:name()/fn:name(nodeset) 返回当前节点的名称或指定节点集的第一个节点
fn:local-name()/fn:local-name(nodeset) 返回当前节点的名称或指定节点集的第一个节点-不带命名空
fn:namespace-uri()/fn:namespace-uri(nodeset) 返回当前节点或指定节点集中第一个节点的命名空间URI
fn:lang(lang) 如果当前节点的语言匹配指定的语言则返回True
fn:root()/fn:root(node) 返回当前节点或指定节点所属的节点树的根节点。通常是文档节点
(7)一般性函数
名称 说明
fn:index-of((item,item,...),searchitem) 返回在项目序列中等于searchitem参数的位置
fn:remove((item,item...),position) 返回由item参数构造的新序列-同时删除position指定的项目
fn:empty(item,item...) 如果参数是空序列则返回True,否则返回False
fn:exists(item,item,...) 如果参数不是空序列,则返回True,否则返回False
fn:distince-values((item,item,...),collation) 返回唯一不同的值
fn:insert-before((item,item,...),pos,inserts) 返回由item参数构造的新序列 - 同时在pos参数指定位置插入inserts参数的值
fn:reverse((item,item,...)) 返回指定的项目的颠倒顺序
fn:subsequence((item,item,...),start,len) 返回start参数指定的位置返回项目序列,序列的长度由len参数指定。第一个项目的位置是1
fn:unordered 依据事先决定的顺序来返回项目
(8)关于布尔值的函数
名称 说明
fn:boolean(arg) 返回数字、字符串或节点集的布尔值
fn:not(arg) 首先通过boolean()函数把参数还原为一个布尔值,如果该布尔值为false则返回true,否则返回false
fn:true() 返回布尔值true
fn:false() 返回布尔值false
由于函数实在太多,因此次数仅仅写了几个示例,展示下用法而已,一般都是写在谓词里。
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument(); //创建文档
doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml"); //加载xml文件 XmlNode node1 = doc.SelectSingleNode("//title[contains(text(),'三')]"); //选取title元素,要求title的内容含有'三'
Console.WriteLine(node1.InnerText); //输出 三国演义 XmlNode node2 = doc.SelectSingleNode("//title[@lang='属性2']"); //获取属性lang的值为属性2的title节点,不管它位于何处
Console.WriteLine(node2.InnerText); XmlNode node3 = doc.SelectSingleNode("//author[starts-with(text(),'吴')]"); //选取任意位置的author节点,其中author的元素值要以 吴 开头
Console.WriteLine(node3.InnerText); //输出 吴承恩 XmlNode node4 = doc.SelectSingleNode("//title[string-length(text())>3]"); //选取值的长度大于3的title元素
Console.WriteLine(node4.InnerText); //输出 三国演义 XmlNode node5 = doc.SelectSingleNode("//price[floor(text())=38]"); //获取 向下取整后值等于38的price元素
Console.WriteLine(node5.InnerText); //输出 38.5 Console.ReadKey();
}
XPath <第四篇>的更多相关文章
- EnjoyingSoft之Mule ESB开发教程第四篇:Mule Expression Language - MEL表达式
目录 1. MEL的优势 2. MEL的使用场景 3. MEL的示例 4. MEL的上下文对象 5. MEL的Variable 6. MEL访问属性 7. MEL操作符 本篇主要介绍Mule表达式语言 ...
- 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)
从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...
- 第四篇 Entity Framework Plus 之 Batch Operations
用 Entity Framework 进行 增,删,改.都是基于Model进行的,且Model都是有状态追踪的.这样Entity Framework才能正常增,删,改. 有时候,要根据某个字段,批量 ...
- 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)
解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...
- 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...
- 深入理解javascript作用域系列第四篇——块作用域
× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
- 前端工程师技能之photoshop巧用系列第四篇——图片格式
× 目录 [1]图片格式 [2]保存设置 前面的话 对于前端来说,图片格式是需要重要掌握的知识.本文是photoshop巧用系列第四篇——图片格式 图片格式 目前在前端的开发中常用的图片格式有jpg. ...
- 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理
温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...
随机推荐
- qt http 下载文件
本文章介绍如何利用HTTP从网站上下载文件.在Qt网络编程中,需要用到协议,即HTTP.它是超文本传输协议,它是一种文件传输协议.对于HTTP就不多解释了. 在Qt网络编程中,需要用到协议,即HTTP ...
- VS IDE环境下,windows GUI(Qt MFC,win32)使用控制台实时打印调试信息
在工程属性的页面下,点击Build Events,在Build Events下点击Post-Build Event. 然后再Command Line里面输入以下命令: editbin /SUBSYST ...
- java I/O之装饰者模式
装饰者: Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案. 装饰者模式意图: 动态的给一个对象添加额外的职责.Decorato ...
- 【转】ubuntu中的Wine详解
原文网址:http://blog.csdn.net/iwtwiioi/article/details/10530561 什么是wine?(转自百度百科,具体看百科) wine,是一款优秀的Linux系 ...
- HDU5584 LCM Walk 数论
LCM Walk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- win10 下安装、配置、启动mysql
1.下载http://dev.mysql.com/downloads/mysql/ 2.Community > MySQL Community Server 3.Other Downloads: ...
- MVC 部分视图
ASP.NET MVC 里的部分视图,相当于 Web Form 里的 User Control.我们的页面往往会有许多重用的地方,可以进行封装重用. 使用部分视图有以下优点: 1. 可以简写代码. ...
- Android Dependencies小差号引起的问题
问题是由于Android Dependencies小差号引起的,下午一搞Android的哥们在群里说最近导入的几个工程每个都是Android Dependencies报错,小差号,我先说解决方法: 方 ...
- 客户Oracle数据库在插入数据的时候报超出最大长度的错误(规避风险)
背景: 项目使用oracle数据,在开发环境测试一些正常.项目部署到客户的服务器上后,系统在添加数据的时候报错.输出错误信息,发现是“超出最大长度”的异常. 但是按照数据库的设计,添加的数据应该在允许 ...
- iOS 无限轮播图的两种实现
首先说一下实现的思想: 用UIScrollView实现,在scrollView上添加3个UIImageView,分别用来显示上一张图片,当前显示的图片,下一张图片.scrollView在不滑动的时候永 ...