zoukankan      html  css  js  c++  java
  • XML基础知识归纳(通俗易懂)

    XML:可扩展标记型语言

    随着json等一些技术的普及,似乎xml的路子越来越窄,虽然xml的一些功能被其他的一些技术代替,但是学习xml还是非常有必要,如果用xml存储一些大量数据,还是有一定优势的,就算你不管这些,但是现有的很多框架以及技术的配置文件都存在于xml中,最起码你得对它的结构以及一些基本用法有一定了解

    (一) 基本概述

    (1) 概念

    XML:Extensible Markup Language:可扩展标记型语言

    标记型:使用标签来操作,html就是一种常见的标记型语言

    可扩展:可以自定义标签,甚至可以用中文写标签 Eg:<person></person <张三><张三>

    (2) 用途

    xml 主要用来存储数据,体现在作配置文件,或者充当小型数据库,在网络中传输数据

    A:配置文件:例如配置mysql数据库

    前面我们常常书写 一个 jdbc.properties文件来做配置文件,好处呢就是如果想修改数据库的信息,不需要修改源代码,只要修改配置文件就可以了,而xml也可以作为配置文件来使用

    url=jdbc:mysql://localhost:3306/db1
    user=root
    password=root99
    driver=com.mysql.jdbc.Driver
    
    <!--例如模拟配置mysql数据库 只为假设,与前面知识对应,实际配置文件后期会很常见-->
    <?xml version="1.0" encoding="UTF-8"?>
    <config>
    	<dbinfo>
    		<dbDriver>com.mysql.jdbc.Driver</dbDriver>
    		<dbUrl>jdbc:mysql://localhost:3306/db1</dbUrl>
    		<username>root</username>
    		<password>root99</password>
    </config>
    

    B:充当小型数据库

    我们可以在xml中存储一些数据,让它充当一个小型的数据库

    <?xml version="1.0" encoding="UTF-8"?>
    <student> 
    	<stu> 
        	<id>001</id>  
        	<name>zhangsan</name>  
        	<age>20</age> 
        </stu>  
    	<stu> 
        	<id>002</id>  
        	<name>lisi</name>  
        	<age>30</age> 
    	</stu>  
    </student>
    

    C:传输数据

    在网络编程中,我们或多或少接触过,例如如何实现一个简单的聊天室,基本原理是这样的,一个服务器端,多个客户端,当客户端1发送数据后,服务器端接收到数据,并且对数据进行一定的审核(是否有非法敏感字)以及格式的处理,再将数据发送到每一个客户端中

    刚开始的时候,我们一般选择使用字符串直接传递内容,但是却不是很利于程序的后期维护,而使用xml就能对后期程序的维护更加友好

    <?xml version="1.0" encoding="UTF-8"?>
    <message id="1">
    	<sender>账号1</sender>
    	<getter>账号2</getter>
    	<content>发送的信息</content>
        <ip>ip地址</ip>
    </message>
    

    (二) xml语法

    xml文档的后缀名为 .xml

    (1) 文档声明

    创建一个xm文件后,第一步就是 必须要有 一个文档声明(写了文档声明之后,表写xml文件的内容)

    <?xml version="1.0" encoding="UTF-8"?>
    
    • version : xml版本,必须写

    • encoding:xml编码 常见编码: GBK、UTF-8、ISO8859-1(不包含中文)

      • 保存时编码和设置打开时候的编码需要一致,否则会出现乱码
    • standalone:是否需要依赖其他文件 yes/no

    (2) 标签的定义

    注意事项

    1. 有始有终:<person></peoson>
    2. 合理嵌套:<aa><bb></bb></aa>
    3. 空格和换行均当做内容来解析,所以可能我们需要注意一些缩进的问题

    名称规则

    1. xml 代码区分大小写
    2. 名称不能以数字或者标点符号开始
    3. 不能以 xml、XML、Xml等开头
    4. 不能包含空格和冒号

    (3) 属性的定义

    1. 一个标签上可有多个属性 <person id1="aaa" id2="bbb"></person>
    2. 属性名称和值之间使用 = 连接,属性值用引号包起来(单引号和双引号都可以)

    (4) 注释

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- xml注释 -->
    

    注释不能嵌套,并且不能放到第一行,第一行必须方式文档声明

    (5) 特殊字符

    如果想在xml中输入特殊字符,需要对字符进行转义,因为 < 等会被当做标签

    字符 转义字符 描述
    & &
    < < 小于号
    > > 大于号
    " " 双引号
    ' ' 单引号

    若多个字符都需要转义,则可以将这些内容存放到CDATA里面

    <![CDATA[ 内容 ]]>
    

    (七) PI指令 (处理指令)

    可以在xml设置样式

    <?xml-stylesheet type="text/css" href="css的路径"?>
    

    (三) xml约束

    为什么需要用到约束呢?比如我们现在定义一个 student.xml文件,我们想要在其中保存关于学生的信息,例如id,name,age,但是如果随便写入一个标签 例如 <你好> 从语法的角度上虽然是符合规范的,但是这显然与我们想要存储的东西没有任何关系,所以我们需要通过xml约束技术,约束xml中只能出现的元素

    分类

    • DTD:一种相对简单的约束技术
    • Schema:一种相对复杂的约束技术,看懂即可

    DTD约束

    (1) dtd的引入方式(三种)

    A:使用内部的dtd文件,即将约束规则定义在xml文档中

    <!DOCTYPE 根元素名称 [
    	<!ELEMENT person (name,age)>
    	<!ELEMENT name (#PCDATA)>
    	<!ELEMENT age (#PCDATA)>
    ]>
    

    B:引入外部的dtd文件

    <!DOCTYPE 根元素名称 SYSTEM "dtd路径">
    

    C:使用外部的dtd文件(网络上的dtd文件)

    <!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">
    
    例如使用 struts2框架 使用配置文件 所使用 外部的dtd文件
    
    <!DOCTYPE struts PUBLIC   "-//Apache Software Foundation//DTD
    Struts Configuration 2.0//EN"    
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    

    (2) 使用dtd定义元素

    <!ELEMENT 元素名 约束>
    

    A:简单元素(没有子元素)

    ELEMENT name (#PCDATA)>
    	(#PCDATA): 约束name是字符串类型
    	EMPTY : 元素为空(没有内容)
    		- <sex></sex>
    	ANY:任意
    

    B:复杂元素

    <!-- 语法 -->
    <!ELEMENT person (id,name,age,)>
    	子元素只能出现一次
    <!ELEMENT 元素名称 (子元素)>
    
    <!-- 子元素出现次数 -->
    * :一次多或多次
    ?:零次或一次
    * :零次或多次
    
    <!-- 子元素直接使用逗号隔开 -->
    	表示元素出现的顺序 
    
    <!-- 子元素直接使用 | -->
    	表示元素只能出现其中的任意一个
    

    (2) 使用dtd定义属性

    <!-- 语法 -->
    <!ATTLIST 元素名称
    	属性名称 属性类型 属性的约束
    >
    
    <!-- 属性类型 -->	CDATA: 字符串
    <!ATTLIST birthday
    	ID1 CDATA #REQUIRED
    >
    
    <!-- 枚举 -->
    表示只能在一定的范围内出现值,但是只能每次出现其中的一个,红绿灯效果
    <!ATTLIST age
    	ID2 (AA|BB|CC)  #REQUIRED
    >
    
    <!-- ID: 值只能是字母或者下划线开头 -->
    <!ATTLIST name 
    	ID3 ID   #REQUIRED
    >
    
    <!-- 属性的约束 -->
    #REQUIRED:属性必须存在
    #IMPLIED:属性可有可无
    #FIXED: 表示一个固定值 #FIXED "AAA"
    	属性的值必须是设置的这个固定值
    		<!ATTLIST sex
    			ID4 CDATA #FIXED "ABC"
    		>
    
    直接值
    	不写属性,使用直接值
    	写了属性,使用设置那个值
    		<!ATTLIST school
    			ID5 CDATA "WWW"
    		>
    

    Schema约束

    schema 符合 xml 的语法,一个 xml 中可以有多个 schema ,多个 schema 使用名称空间区分(类似于java包名)dtd 里面有PCDATA类型,但是在 schema 里面可以支持更多的数据类型

    后缀名:xsd

    引入:
    填写xml文档的根元素
    
    引入xsi前缀.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	表示xml文件是一个约束文件
    	
    引入xsd文件命名空间.  xsi:schemaLocation="http://www.bwh.cn/xml  student.xsd"
    	使用一个使用schema约束文件,直接通过这个地址引入约束文件
    	  通常使用一个url地址防止重名
    	  
    为每一个xsd约束声明一个前缀,作为标识  xmlns="http://www.bwh.cn/xml" 
    

    (1) 看xml中有多少个元素

    <element>
    

    (2) 看简单元素和复杂元素

    <element name="person">
    <complexType>
    <sequence>
    	<element name="name" type="string"></element>
    					<element name="age" type="int"></element>
    </sequence>
    </complexType>
    </element>
    

    (3) 被约束文件里面引入约束文件

    <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.bwh.cn/20151111"
    xsi:schemaLocation="http://www.bwh.cn/20151111 1.xsd">
    
    			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    				-- 表示xml是一个被约束文件
    			xmlns="http://www.bwh.cn/20151111"
    				-- 是约束文档里面 targetNamespace
    			xsi:schemaLocation="http://www.bwh.cn/20151111 1.xsd">
    				-- targetNamespace 空格  约束文档的地址路径
    

    可以约束属性

    A: <sequence>:表示元素的出现的顺序
    B: <all>: 元素只能出现一次
    C: <choice>:元素只能出现其中的一个
    D: maxOccurs="unbounded": 表示元素的出现的次数
    E: <any></any>:表示任意元素
    
    写在复杂元素里面
    写在 </complexType>之前
    
    --
    <attribute name="id1" type="int" use="required"></attribute>
    	- name: 属性名称
    	- type:属性类型 int stirng
    	- use:属性是否必须出现 required
    

    (四) xml的解析

    很简单的理解解析:有一个xml,在其中读取出需要的数据

    (1) 解析方式 dom和sax

    DOM:根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象,一次性加载进内存

    • 优点:操作方便,很容易实现增删改操作

    • 缺点:占内存,有造成内存溢出风险

    SAX:采用事件驱动,边读边解析,解析到某一个对象,返回对象名称

    • 优点:不占内存
    • 缺点:只能读取,不能实现增删改操作

    (2) 解析器

    想要解析xml,我们必须了解解析器,不同的公司和组织,提供了针对dom和sax方式的解析器,通过api方式提供 (今天着重讲解两种比较常用的)

    1. jaxp:sun公司所提供针对dom和sax的解析器,效率略低
    2. dim4j:非常优秀的解析器,在实际开发中比较常用
    3. jdom:jdom组织所提供的针对dom和sax解析器
    4. jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
    5. Pull:Android操作系统内置的解析器,sax方式的

    (3) 使用 dom4 操作 xml

    注意:下面的所有java代码中,由于我的代码写在Module中,所以路径加了名字,若直接创建的是项目,只写src/s1.xml即可

    <?xml version="1.0" encoding="UTF-8"?>
    <student>
        <stu id1="love">
            <name>zhangsan</name>
            <age>20</age>
        </stu>
        <stu>
            <name>lisi</name>
            <age>30</age>
        </stu>
    </student>
    

    ※ 使用dom4j实现查询xml操作

    (一)查询所有name元素里面的值

    package cn.ideal.xml.dom4j;
    
    /*
       1、创建解析器
       2、得到document
       3、得到根节点  getRootElement() 返回Element
       4、得到所有的p1标签
          * elements("p1") 返回list集合
          * 遍历list得到每一个p1
       5、得到name
          * 在p1下面执行 element("name")方法 返回Element
       6、得到name里面的值
          * getText方法得到值
    */
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import java.util.List;
    
    public class TestDom4j1 {
        //查询xml中所有name元素的值
        public static void main(String[] args) throws DocumentException {
            //创建解析器
            SAXReader saxReader = new SAXReader();
            //得到document
            Document document = saxReader.read("code-04_xml/src/s1.xml");
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到stu
            List<Element> list = rootElement.elements("stu");
    
            //遍历list
            for (Element element : list) {
                //element是每一个元素
                //得到name里面的值
                Element name1 = element.element("name");
                //得到name里面的值
                String s = name1.getText();
                System.out.println(s);
            }
        }
    }
    //运行结果
    zhangsan
    lisi
    

    (二)查询第一个name元素的值

    package cn.ideal.xml.dom4j;
    
    /*
        1、创建解析器
        2、得到document
        3、得到根节点
        4、得到第一个stu元素
            element("stu")方法 返回Element
        5、得到p1下面的name元素
            element("name")方法 返回Element
        6、得到name元素里面的值
            getText方法
     */
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    public class TestDom4j2 {
        public static void main(String[] args) throws DocumentException {
            //创建解析器
            SAXReader saxReader = new SAXReader();
            //得到document对象
            Document document = saxReader.read("code-04_xml/src/s1.xml");
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //得到stu下面的name元素
            Element name1 = stu.element("name");
            //得到name的值
            String s1 = name1.getText();
            System.out.println(s1);
        }
    }
    
    //运行结果
    zhangsan
    

    (三)获取第二个name元素的值

    package cn.ideal.xml.dom4j;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import java.util.List;
    
    /*
        1、创建解析器
        2、得到document
        3、得到根节点
        4、得到所有的stu
            返回 list集合
        5、遍历得到第二个stu
            使用list下标得到 get方法,集合的下标从 0 开始,想要得到第二个值,下标写 1
        6、得到第二个p1下面的name
            element("name")方法 返回Element
        7、得到name的值
            getText方法
     */
    public class TestDom4j3 {
        public static void main(String[] args) throws DocumentException {
            //创建解析器
            SAXReader saxReader = new SAXReader();
            //得到document
            Document document = saxReader.read("code-04_xml/src/s1.xml");
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到所有stu
            List<Element> list = rootElement.elements("stu");
            //得到第二个stu
            Element stu2 = list.get(1);
            //得到stu下的name
            Element name2 = stu2.element("name");
            //得到name里面的值
            String s2 = name2.getText();
            System.out.println(s2);
        }
    }
    

    ※ 使用dom4j实现添加操作

    **(一)在第一个p1标签末尾添加一个元素 **<sex>male</sex>

    package cn.ideal.xml.dom4j;
    
    import org.dom4j.Document;
    
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    import java.io.FileOutputStream;
    
    
    /*
        1、创建解析器
        2、得到document
        3、得到根节点
    
        4、获取到第一个p1
            使用element方法
        5、在p1下面添加元素
            在p1上面直接使用 addElement("标签名称")方法 返回一个Element
    
        6、在添加完成之后的元素下面添加文本
           在sex上直接使用 setText("文本内容")方法
        7、回写xml
            格式化 OutputFormat,使用 createPrettyPrint方法,表示一个漂亮的格式
            使用类XMLWriter 直接new 这个类 ,传递两个参数
            第一个参数是xml文件路径 new FileOutputStream("路径")
            第二个参数是格式化类的值
    */
    public class TestDom4j4 {
        public static void main(String[] args) throws Exception {
            //创建解析器
            SAXReader saxReader = new SAXReader();
            //得到document
            Document document = saxReader.read("code-04_xml/src/s1.xml");
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //在stu下面直接添加元素
            Element sex1 = stu.addElement("sex");
            //在sex下面添加文本
            sex1.setText("male");
    
            //回写xml
            OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有缩进效果
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("code-04_xml/src/s1.xml"), prettyPrint);
            xmlWriter.write(document);
        }
    }
    

    写一个工具类,简化操作

    封装方法的操作,可以省略创建解析器 得到document 以及回写xml的方法,把传递的文件路径,封装成一个常量

    好处:可以提高开发速度,可以提交代码可维护性

    比如想要修改文件路径(名称),这个时候只需要修改常量的值就可以了,其他代码不需要做任何改变

    package cn.ideal.xml.utils;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Dom4jUtils {
        public static final String PATH = "code-04_xml/src/s1.xml";
    
        //返回document
        public static Document getDocument(String path) {
            //创建解析器
            SAXReader saxReader = new SAXReader();
            //得到document
            try {
                Document document = saxReader.read(path);
                return document;
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //回写xml的方法
        public static void xmlWriters(String path, Document document) {
            try {
                OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有缩进效果
                XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), prettyPrint);
                xmlWriter.write(document);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    我们上面执行添加操作的代码就可以简化为

    package cn.ideal.xml.dom4j;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    
    
    public class TestDom4j5 {
        public static void main(String[] args) throws Exception {
    
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //在stu下面直接添加元素
            Element sex1 = stu.addElement("sex");
            //在sex下面添加文本
            sex1.setText("male");
    
            //回写xml
            Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
        }
    }
    
    

    **(二)使用dom4j实现在特定位置添加元素 **

    在第一个stu下面的name标签前添加 <id>001</id>

    package cn.ideal.xml.dom4j;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    
    import java.util.List;
    
    /*
        1、创建解析器
        2、得到document
        3、得到根节点
        4、获取到第一个p1
    
        5、获取p1下面的所有的元素
               ** elements()方法 返回 list集合
    
            ** 使用list里面的方法,在特定位置添加元素
           ** 首先创建元素 在元素下面创建文本
                  - 使用DocumentHelper类方法createElement创建标签
                  - 把文本添加到标签下面 使用 setText("文本内容")方法
    
             ** list集合里面的 add(int index, E element)
               - 第一个参数是 位置 下标,从0开始
               - 第二个参数是 要添加的元素
          6、回写xml
    */
    public class TestDom4j6 {
        //在第一个stu下面的name标签前添加<id>001</id>
        public static void main(String[] args) {
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //获取stu下全部元素
            List<Element> list = stu.elements();
            //创建元素
            Element id = DocumentHelper.createElement("id");
            //在id下面创建文本
            id.setText("001");
            //在特定位置添加
            list.add(0, id);
    
            Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
        }
    }
    

    **(三)使用dom4j实现修改节点的操作 **

    修改第一个p1下面的age元素的值为18

    package cn.ideal.xml.dom4j;
    /*
        1、得到document
       	2、得到根节点,然后再得到第一个p1元素
       	3、得到第一个p1下面的age
          element("")方法
       	4、修改值是 30
           使用setText("文本内容")方法
       	5、回写xml
    */
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    
    public class TestDom4j7 {
        public static void main(String[] args) {
            //得到document
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //得到第一个stu下面的age
            Element age = stu.element("age");
            age.setText("18");
            //回写xml
            Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
        }
    }
    

    ※ 使用dom4j实现删除节点的操作

    package cn.ideal.xml.dom4j;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    
    public class TestDom4j8 {
        public static void main(String[] args) {
            //得到document
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //得到第一个stu下面的age
            Element id = stu.element("id");
    
            stu.remove(id);
            //回写xml
            Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
        }
    }
    

    使用dom4j获取属性的操作

    package cn.ideal.xml.dom4j;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    
    public class TestDom4j9 {
        public static void main(String[] args) {
            //得到document
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到第一个stu元素
            Element stu = rootElement.element("stu");
            //得到stu里面的属性值
            String value = stu.attributeValue("id1");
            System.out.println(value);
        }
    }
    

    (4) 使用dom4j支持xpath具体操作

    XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言

    默认的情况下,dom4j不支持xpath

    如果想用,需要引入支持xpath的jar包,使用 jaxen-1.1-beta-6.jar

    第一种形式
    	/AAA/CCC/BBB: 表示一层一层的,AAA下面CCC下面的BBB
    第二种形式
    	//BBB: 表示和这个名称相同,表示只要名称是BBB,都得到
    第三种形式
    	/*: 所有元素
    第四种形式
    	BBB[1]: 表示第一个BBB元素
    	BBB[last()]:表示最后一个BBB元素
    第五种形式
    	//BBB[@id]: 表示只要BBB元素上面有id属性,都得到
    第六种形式
    	//BBB[@id='b1'] 表示元素名称是BBB,在BBB上面有id属性,并且id的属性值是b1
    

    dom4j里面提供了两个方法,用来支持xpath

    //获取多个节点
    selectNodes("xpath表达式")
    
    //获取一个节点
    selectSingleNode("xpath表达式")
    

    (一)使用xpath实现:查询xml中所有name元素的值

    package cn.ideal.xml.dom4j.xpath;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Node;
    
    import java.util.List;
    
    public class TestDom4jXpath1 {
        //查询xml中所有name元素的值
        public static void main(String[] args) {
            //得到document
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            //获取所有name元素
            List<Node> list = document.selectNodes("//name");
            //遍历list集合
            for (Node node : list) {
                //node是每一个name元素
                //得到name元素里面的值
                String s = node.getText();
                System.out.println(s);
            }
        }
    }
    

    (二)使用xpath实现:获取第一个stu下面的name的值

    package cn.ideal.xml.dom4j.xpath;
    
    import cn.ideal.xml.utils.Dom4jUtils;
    import org.dom4j.Document;
    import org.dom4j.Node;
    
    public class TestDom4jXpath2 {
        public static void main(String[] args) {
            //得到document
            Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
            Node name1 = document.selectSingleNode("//stu[@id1='love']/name");
            //得到name里面的值
            String s1 = name1.getText();
            System.out.println(s1);
        }
    }
    

    (4) 使用 Jsoup 操作 xml

    package cn.ideal.xml.jsoup;
    
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    public class JsoupDemo1 {
        public static void main(String[] args) throws IOException {
            //获取Documnet对象
            //通过类加载器,获取student.xml的path
            String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
            //解析xml文档,加载文档进内存,获取dom树 --> Document
            Document document = Jsoup.parse(new File(path), "utf-8");
            //获取元素对象 Element
            Elements elements = document.getElementsByTag("name");
    
            //获取第一个name
            Element element = elements.get(0);
            //获取数据
            String name = element.text();
            System.out.println(name);
        }
    }
    

    对上述常用对象的解释

    1. Jsoup:工具类:可以解析html或xml文档,返回Document

    parse:

    //解析xml或html文件
    parse (File in, String charsetName)
    
    //解析xml或html字符串
    parse (String html)
    
    //通过网络路径获取指定的html或xml
    parse (URL url, int timeoutMillis)
    

    2. Document:文档对象:代表内存中的dom树

    A:获取Element对象

    //根据id属性值获取唯一的element对象
    getElementById (String id)
    
    //根据标签名称获取元素对象集合
    getElementsByTag (String tagName)
    
    //根据属性名称获取元素对象集合
    getElementsByAttribute (String key)
    
    //根据对应的属性名和属性值获取元素对象集合
    getElementsByAttributeValue (String key, String value)
    

    3. Elements:元素Element对象的集合。可以近似的认为 ArrayList<Element>

    A:获取Element对象,同2中

    B:获取属性值

    String attr(String key):根据属性名称获取属性值
    

    C:获取文本内容

    //获取文本内容
    String text()
    
    //获取标签体的所有内容
    String html()
    

    两种更加快捷的查询方式

    selector:选择器

    Elements select(String cssQuery)
    //具体语法,看文档格式
    
    <?xml version="1.0" encoding="UTF-8"?>
    <student>
        <stu number="stu_001">
            <name id="ideal">zhangsan</name>
            <age>18</age>
        </stu>
        <stu number="stu_002">
            <name>lisi</name>
            <age>30</age>
        </stu>
    </student>
    
    package cn.ideal.xml.jsoup;
    
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    public class SelectorDemo {
        public static void main(String[] args) throws IOException {
            //获取Documnet对象
            //通过类加载器,获取student.xml的path
            String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
            //解析xml文档,加载文档进内存,获取dom树 --> Document
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //查询name标签
            Elements elements1 = document.select("name");
            System.out.println(elements1);
    
            System.out.println("--------------");
    
            //查询id值为 stu_001
            Elements elements2 = document.select("#ideal");
            System.out.println(elements2);
    
            System.out.println("--------------");
    
            Elements elements3 = document.select("stu[number='stu_001']");
            System.out.println(elements3);
    
        }
    }
    
    //运行结果
    <name id="ideal">
     zhangsan
    </name>
    <name>
     lisi
    </name>
    --------------
    <name id="ideal">
     zhangsan
    </name>
    --------------
    <stu number="stu_001"> 
     <name id="ideal">
      zhangsan
     </name> 
     <age>
      18
     </age> 
    </stu>
    

    XPath

    package cn.ideal.xml.jsoup;
    
    import cn.wanghaomiao.xpath.model.JXDocument;
    import cn.wanghaomiao.xpath.model.JXNode;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    
    import java.io.File;
    import java.util.List;
    
    public class XpathDemo {
        public static void main(String[] args) throws Exception {
    //获取Documnet对象
            //通过类加载器,获取student.xml的path
            String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
            //解析xml文档,加载文档进内存,获取dom树 --> Document
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //创建JXDocument对象
            JXDocument jxDocument = new JXDocument(document);
    
            //结合xpath语法查询
            List<JXNode> jxNodes = jxDocument.selN("//stu");
            for (JXNode jxNode : jxNodes) {
                System.out.println(jxNode);
            }
        }
    }
    
    //运行结果
    <stu number="stu_001"> 
     <name id="ideal">
      zhangsan
     </name> 
     <age>
      18
     </age> 
    </stu>
    <stu number="stu_002"> 
     <name>
      lisi
     </name> 
     <age>
      30
     </age> 
    </stu>
    
    //查询stu标签下的name标签
    List<JXNode> jxNodes = jxDocument.selN("//student/name");
    
    //查询stu标签下带有id属性且属性值ideal的name标签
    List<JXNode> jxNodes = jxDocument.selN("//stu/name[@id='ideal']");
    

    结尾:

    如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !_

    如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)

    在这里的我们素不相识,却都在为了自己的梦而努力 ❤

    一个坚持推送原创Java技术的公众号:理想二旬不止

  • 相关阅读:
    PAT 甲级1135. Is It A Red-Black Tree (30)
    AVL树模板
    定时器模板
    Listview模板
    Hash二次探测
    BFS小结
    STL之set篇
    完全二叉树-已知中序排序,输出广度排序
    BZOJ2037: [Sdoi2008]Sue的小球
    poj1157LITTLE SHOP OF FLOWERS
  • 原文地址:https://www.cnblogs.com/ideal-20/p/11364679.html
Copyright © 2011-2022 走看看