zoukankan      html  css  js  c++  java
  • 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 选取当前节点

       与轴有关的两个重要概念:

    1. 位置;
    2. 步;

       位置路径可以是绝对的,也可以是相对的。

       绝对路径表达式:

     /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();
            }
  • 相关阅读:
    【百度地图API】如何快速创建带有标注的地图?——快速创建地图工具+如何标注商家
    【百度地图API】百度做了一个艰难的决定——取消密钥机制!!
    【设计师工具】3个好用的在线配色工具
    【百度地图API】建立全国银行位置查询系统(二)——怎样为地图添加控件
    【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍
    【百度地图API】多家地图API文件大小对比
    “街坊”房产数字平台,昔日的思想,曾经的努力
    软件工程之感想
    .net执行性能,Winform性能优化?如何提高.net程序性能
    个人之思考整理
  • 原文地址:https://www.cnblogs.com/kissdodog/p/2933964.html
Copyright © 2011-2022 走看看