XML:可扩展标记型语言

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

(一) 基本概述

(1) 概念

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

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

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

(2) 用途

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

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

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

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

B:充当小型数据库

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <student>
  3. <stu>
  4. <id>001</id>
  5. <name>zhangsan</name>
  6. <age>20</age>
  7. </stu>
  8. <stu>
  9. <id>002</id>
  10. <name>lisi</name>
  11. <age>30</age>
  12. </stu>
  13. </student>

C:传输数据

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

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

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

(二) xml语法

xml文档的后缀名为 .xml

(1) 文档声明

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

  1. <?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) 注释

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

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

(5) 特殊字符

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

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

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

  1. <![CDATA[ 内容 ]]>

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

可以在xml设置样式

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

(三) xml约束

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

分类

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

DTD约束

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

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

  1. <!DOCTYPE 根元素名称 [
  2. <!ELEMENT person (name,age)>
  3. <!ELEMENT name (#PCDATA)>
  4. <!ELEMENT age (#PCDATA)>
  5. ]>

B:引入外部的dtd文件

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

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

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

(2) 使用dtd定义元素

  1. <!ELEMENT 元素名 约束>

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

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

B:复杂元素

  1. <!-- 语法 -->
  2. <!ELEMENT person (id,name,age,)>
  3. 子元素只能出现一次
  4. <!ELEMENT 元素名称 (子元素)>
  5. <!-- 子元素出现次数 -->
  6. * :一次多或多次
  7. ?:零次或一次
  8. * :零次或多次
  9. <!-- 子元素直接使用逗号隔开 -->
  10. 表示元素出现的顺序
  11. <!-- 子元素直接使用 | -->
  12. 表示元素只能出现其中的任意一个

(2) 使用dtd定义属性

  1. <!-- 语法 -->
  2. <!ATTLIST 元素名称
  3. 属性名称 属性类型 属性的约束
  4. >
  5. <!-- 属性类型 --> CDATA: 字符串
  6. <!ATTLIST birthday
  7. ID1 CDATA #REQUIRED
  8. >
  9. <!-- 枚举 -->
  10. 表示只能在一定的范围内出现值,但是只能每次出现其中的一个,红绿灯效果
  11. <!ATTLIST age
  12. ID2 (AA|BB|CC) #REQUIRED
  13. >
  14. <!-- ID: 值只能是字母或者下划线开头 -->
  15. <!ATTLIST name
  16. ID3 ID #REQUIRED
  17. >
  18. <!-- 属性的约束 -->
  19. #REQUIRED:属性必须存在
  20. #IMPLIED:属性可有可无
  21. #FIXED: 表示一个固定值 #FIXED "AAA"
  22. 属性的值必须是设置的这个固定值
  23. <!ATTLIST sex
  24. ID4 CDATA #FIXED "ABC"
  25. >
  26. 直接值
  27. 不写属性,使用直接值
  28. 写了属性,使用设置那个值
  29. <!ATTLIST school
  30. ID5 CDATA "WWW"
  31. >

Schema约束

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

后缀名:xsd

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

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

  1. <element>

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

  1. <element name="person">
  2. <complexType>
  3. <sequence>
  4. <element name="name" type="string"></element>
  5. <element name="age" type="int"></element>
  6. </sequence>
  7. </complexType>
  8. </element>

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

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

可以约束属性

  1. A: <sequence>:表示元素的出现的顺序
  2. B: <all>: 元素只能出现一次
  3. C: <choice>:元素只能出现其中的一个
  4. D: maxOccurs="unbounded" 表示元素的出现的次数
  5. E: <any></any>:表示任意元素
  6. 写在复杂元素里面
  7. 写在 </complexType>之前
  8. --
  9. <attribute name="id1" type="int" use="required"></attribute>
  10. - name: 属性名称
  11. - type:属性类型 int stirng
  12. - 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即可

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <student>
  3. <stu id1="love">
  4. <name>zhangsan</name>
  5. <age>20</age>
  6. </stu>
  7. <stu>
  8. <name>lisi</name>
  9. <age>30</age>
  10. </stu>
  11. </student>

※ 使用dom4j实现查询xml操作

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

  1. package cn.ideal.xml.dom4j;
  2. /*
  3. 1、创建解析器
  4. 2、得到document
  5. 3、得到根节点 getRootElement() 返回Element
  6. 4、得到所有的p1标签
  7. * elements("p1") 返回list集合
  8. * 遍历list得到每一个p1
  9. 5、得到name
  10. * 在p1下面执行 element("name")方法 返回Element
  11. 6、得到name里面的值
  12. * getText方法得到值
  13. */
  14. import org.dom4j.Document;
  15. import org.dom4j.DocumentException;
  16. import org.dom4j.Element;
  17. import org.dom4j.io.SAXReader;
  18. import java.util.List;
  19. public class TestDom4j1 {
  20. //查询xml中所有name元素的值
  21. public static void main(String[] args) throws DocumentException {
  22. //创建解析器
  23. SAXReader saxReader = new SAXReader();
  24. //得到document
  25. Document document = saxReader.read("code-04_xml/src/s1.xml");
  26. //得到根节点
  27. Element rootElement = document.getRootElement();
  28. //得到stu
  29. List<Element> list = rootElement.elements("stu");
  30. //遍历list
  31. for (Element element : list) {
  32. //element是每一个元素
  33. //得到name里面的值
  34. Element name1 = element.element("name");
  35. //得到name里面的值
  36. String s = name1.getText();
  37. System.out.println(s);
  38. }
  39. }
  40. }
  41. //运行结果
  42. zhangsan
  43. lisi

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

  1. package cn.ideal.xml.dom4j;
  2. /*
  3. 1、创建解析器
  4. 2、得到document
  5. 3、得到根节点
  6. 4、得到第一个stu元素
  7. element("stu")方法 返回Element
  8. 5、得到p1下面的name元素
  9. element("name")方法 返回Element
  10. 6、得到name元素里面的值
  11. getText方法
  12. */
  13. import org.dom4j.Document;
  14. import org.dom4j.DocumentException;
  15. import org.dom4j.Element;
  16. import org.dom4j.io.SAXReader;
  17. public class TestDom4j2 {
  18. public static void main(String[] args) throws DocumentException {
  19. //创建解析器
  20. SAXReader saxReader = new SAXReader();
  21. //得到document对象
  22. Document document = saxReader.read("code-04_xml/src/s1.xml");
  23. //得到根节点
  24. Element rootElement = document.getRootElement();
  25. //得到第一个stu元素
  26. Element stu = rootElement.element("stu");
  27. //得到stu下面的name元素
  28. Element name1 = stu.element("name");
  29. //得到name的值
  30. String s1 = name1.getText();
  31. System.out.println(s1);
  32. }
  33. }
  34. //运行结果
  35. zhangsan

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

  1. package cn.ideal.xml.dom4j;
  2. import org.dom4j.Document;
  3. import org.dom4j.DocumentException;
  4. import org.dom4j.Element;
  5. import org.dom4j.io.SAXReader;
  6. import java.util.List;
  7. /*
  8. 1、创建解析器
  9. 2、得到document
  10. 3、得到根节点
  11. 4、得到所有的stu
  12. 返回 list集合
  13. 5、遍历得到第二个stu
  14. 使用list下标得到 get方法,集合的下标从 0 开始,想要得到第二个值,下标写 1
  15. 6、得到第二个p1下面的name
  16. element("name")方法 返回Element
  17. 7、得到name的值
  18. getText方法
  19. */
  20. public class TestDom4j3 {
  21. public static void main(String[] args) throws DocumentException {
  22. //创建解析器
  23. SAXReader saxReader = new SAXReader();
  24. //得到document
  25. Document document = saxReader.read("code-04_xml/src/s1.xml");
  26. //得到根节点
  27. Element rootElement = document.getRootElement();
  28. //得到所有stu
  29. List<Element> list = rootElement.elements("stu");
  30. //得到第二个stu
  31. Element stu2 = list.get(1);
  32. //得到stu下的name
  33. Element name2 = stu2.element("name");
  34. //得到name里面的值
  35. String s2 = name2.getText();
  36. System.out.println(s2);
  37. }
  38. }

※ 使用dom4j实现添加操作

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

  1. package cn.ideal.xml.dom4j;
  2. import org.dom4j.Document;
  3. import org.dom4j.Element;
  4. import org.dom4j.io.OutputFormat;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. import java.io.FileOutputStream;
  8. /*
  9. 1、创建解析器
  10. 2、得到document
  11. 3、得到根节点
  12. 4、获取到第一个p1
  13. 使用element方法
  14. 5、在p1下面添加元素
  15. 在p1上面直接使用 addElement("标签名称")方法 返回一个Element
  16. 6、在添加完成之后的元素下面添加文本
  17. 在sex上直接使用 setText("文本内容")方法
  18. 7、回写xml
  19. 格式化 OutputFormat,使用 createPrettyPrint方法,表示一个漂亮的格式
  20. 使用类XMLWriter 直接new 这个类 ,传递两个参数
  21. 第一个参数是xml文件路径 new FileOutputStream("路径")
  22. 第二个参数是格式化类的值
  23. */
  24. public class TestDom4j4 {
  25. public static void main(String[] args) throws Exception {
  26. //创建解析器
  27. SAXReader saxReader = new SAXReader();
  28. //得到document
  29. Document document = saxReader.read("code-04_xml/src/s1.xml");
  30. //得到根节点
  31. Element rootElement = document.getRootElement();
  32. //得到第一个stu元素
  33. Element stu = rootElement.element("stu");
  34. //在stu下面直接添加元素
  35. Element sex1 = stu.addElement("sex");
  36. //在sex下面添加文本
  37. sex1.setText("male");
  38. //回写xml
  39. OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有缩进效果
  40. XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("code-04_xml/src/s1.xml"), prettyPrint);
  41. xmlWriter.write(document);
  42. }
  43. }

写一个工具类,简化操作

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

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

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

  1. package cn.ideal.xml.utils;
  2. import org.dom4j.Document;
  3. import org.dom4j.DocumentException;
  4. import org.dom4j.io.OutputFormat;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. public class Dom4jUtils {
  10. public static final String PATH = "code-04_xml/src/s1.xml";
  11. //返回document
  12. public static Document getDocument(String path) {
  13. //创建解析器
  14. SAXReader saxReader = new SAXReader();
  15. //得到document
  16. try {
  17. Document document = saxReader.read(path);
  18. return document;
  19. } catch (DocumentException e) {
  20. e.printStackTrace();
  21. }
  22. return null;
  23. }
  24. //回写xml的方法
  25. public static void xmlWriters(String path, Document document) {
  26. try {
  27. OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//有缩进效果
  28. XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), prettyPrint);
  29. xmlWriter.write(document);
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. }

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

  1. package cn.ideal.xml.dom4j;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.Element;
  5. public class TestDom4j5 {
  6. public static void main(String[] args) throws Exception {
  7. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  8. //得到根节点
  9. Element rootElement = document.getRootElement();
  10. //得到第一个stu元素
  11. Element stu = rootElement.element("stu");
  12. //在stu下面直接添加元素
  13. Element sex1 = stu.addElement("sex");
  14. //在sex下面添加文本
  15. sex1.setText("male");
  16. //回写xml
  17. Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
  18. }
  19. }

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

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

  1. package cn.ideal.xml.dom4j;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.DocumentHelper;
  5. import org.dom4j.Element;
  6. import java.util.List;
  7. /*
  8. 1、创建解析器
  9. 2、得到document
  10. 3、得到根节点
  11. 4、获取到第一个p1
  12. 5、获取p1下面的所有的元素
  13. ** elements()方法 返回 list集合
  14. ** 使用list里面的方法,在特定位置添加元素
  15. ** 首先创建元素 在元素下面创建文本
  16. - 使用DocumentHelper类方法createElement创建标签
  17. - 把文本添加到标签下面 使用 setText("文本内容")方法
  18. ** list集合里面的 add(int index, E element)
  19. - 第一个参数是 位置 下标,从0开始
  20. - 第二个参数是 要添加的元素
  21. 6、回写xml
  22. */
  23. public class TestDom4j6 {
  24. //在第一个stu下面的name标签前添加<id>001</id>
  25. public static void main(String[] args) {
  26. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  27. //得到根节点
  28. Element rootElement = document.getRootElement();
  29. //得到第一个stu元素
  30. Element stu = rootElement.element("stu");
  31. //获取stu下全部元素
  32. List<Element> list = stu.elements();
  33. //创建元素
  34. Element id = DocumentHelper.createElement("id");
  35. //在id下面创建文本
  36. id.setText("001");
  37. //在特定位置添加
  38. list.add(0, id);
  39. Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
  40. }
  41. }

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

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

  1. package cn.ideal.xml.dom4j;
  2. /*
  3. 1、得到document
  4. 2、得到根节点,然后再得到第一个p1元素
  5. 3、得到第一个p1下面的age
  6. element("")方法
  7. 4、修改值是 30
  8. 使用setText("文本内容")方法
  9. 5、回写xml
  10. */
  11. import cn.ideal.xml.utils.Dom4jUtils;
  12. import org.dom4j.Document;
  13. import org.dom4j.Element;
  14. public class TestDom4j7 {
  15. public static void main(String[] args) {
  16. //得到document
  17. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  18. //得到根节点
  19. Element rootElement = document.getRootElement();
  20. //得到第一个stu元素
  21. Element stu = rootElement.element("stu");
  22. //得到第一个stu下面的age
  23. Element age = stu.element("age");
  24. age.setText("18");
  25. //回写xml
  26. Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
  27. }
  28. }

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

  1. package cn.ideal.xml.dom4j;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.Element;
  5. public class TestDom4j8 {
  6. public static void main(String[] args) {
  7. //得到document
  8. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  9. //得到根节点
  10. Element rootElement = document.getRootElement();
  11. //得到第一个stu元素
  12. Element stu = rootElement.element("stu");
  13. //得到第一个stu下面的age
  14. Element id = stu.element("id");
  15. stu.remove(id);
  16. //回写xml
  17. Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document);
  18. }
  19. }

使用dom4j获取属性的操作

  1. package cn.ideal.xml.dom4j;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.Element;
  5. public class TestDom4j9 {
  6. public static void main(String[] args) {
  7. //得到document
  8. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  9. //得到根节点
  10. Element rootElement = document.getRootElement();
  11. //得到第一个stu元素
  12. Element stu = rootElement.element("stu");
  13. //得到stu里面的属性值
  14. String value = stu.attributeValue("id1");
  15. System.out.println(value);
  16. }
  17. }

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

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

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

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

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

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

  1. //获取多个节点
  2. selectNodes("xpath表达式")
  3. //获取一个节点
  4. selectSingleNode("xpath表达式")

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

  1. package cn.ideal.xml.dom4j.xpath;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.Node;
  5. import java.util.List;
  6. public class TestDom4jXpath1 {
  7. //查询xml中所有name元素的值
  8. public static void main(String[] args) {
  9. //得到document
  10. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  11. //获取所有name元素
  12. List<Node> list = document.selectNodes("//name");
  13. //遍历list集合
  14. for (Node node : list) {
  15. //node是每一个name元素
  16. //得到name元素里面的值
  17. String s = node.getText();
  18. System.out.println(s);
  19. }
  20. }
  21. }

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

  1. package cn.ideal.xml.dom4j.xpath;
  2. import cn.ideal.xml.utils.Dom4jUtils;
  3. import org.dom4j.Document;
  4. import org.dom4j.Node;
  5. public class TestDom4jXpath2 {
  6. public static void main(String[] args) {
  7. //得到document
  8. Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH);
  9. Node name1 = document.selectSingleNode("//stu[@id1='love']/name");
  10. //得到name里面的值
  11. String s1 = name1.getText();
  12. System.out.println(s1);
  13. }
  14. }

(4) 使用 Jsoup 操作 xml

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

对上述常用对象的解释

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

parse:

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

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

A:获取Element对象

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

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

A:获取Element对象,同2中

B:获取属性值

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

C:获取文本内容

  1. //获取文本内容
  2. String text()
  3. //获取标签体的所有内容
  4. String html()

两种更加快捷的查询方式

selector:选择器

  1. Elements select(String cssQuery)
  2. //具体语法,看文档格式
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <student>
  3. <stu number="stu_001">
  4. <name id="ideal">zhangsan</name>
  5. <age>18</age>
  6. </stu>
  7. <stu number="stu_002">
  8. <name>lisi</name>
  9. <age>30</age>
  10. </stu>
  11. </student>
  1. package cn.ideal.xml.jsoup;
  2. import org.jsoup.Jsoup;
  3. import org.jsoup.nodes.Document;
  4. import org.jsoup.select.Elements;
  5. import java.io.File;
  6. import java.io.IOException;
  7. public class SelectorDemo {
  8. public static void main(String[] args) throws IOException {
  9. //获取Documnet对象
  10. //通过类加载器,获取student.xml的path
  11. String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
  12. //解析xml文档,加载文档进内存,获取dom树 --> Document
  13. Document document = Jsoup.parse(new File(path), "utf-8");
  14. //查询name标签
  15. Elements elements1 = document.select("name");
  16. System.out.println(elements1);
  17. System.out.println("--------------");
  18. //查询id值为 stu_001
  19. Elements elements2 = document.select("#ideal");
  20. System.out.println(elements2);
  21. System.out.println("--------------");
  22. Elements elements3 = document.select("stu[number='stu_001']");
  23. System.out.println(elements3);
  24. }
  25. }
  26. //运行结果
  27. <name id="ideal">
  28. zhangsan
  29. </name>
  30. <name>
  31. lisi
  32. </name>
  33. --------------
  34. <name id="ideal">
  35. zhangsan
  36. </name>
  37. --------------
  38. <stu number="stu_001">
  39. <name id="ideal">
  40. zhangsan
  41. </name>
  42. <age>
  43. 18
  44. </age>
  45. </stu>

XPath

  1. package cn.ideal.xml.jsoup;
  2. import cn.wanghaomiao.xpath.model.JXDocument;
  3. import cn.wanghaomiao.xpath.model.JXNode;
  4. import org.jsoup.Jsoup;
  5. import org.jsoup.nodes.Document;
  6. import java.io.File;
  7. import java.util.List;
  8. public class XpathDemo {
  9. public static void main(String[] args) throws Exception {
  10. //获取Documnet对象
  11. //通过类加载器,获取student.xml的path
  12. String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
  13. //解析xml文档,加载文档进内存,获取dom树 --> Document
  14. Document document = Jsoup.parse(new File(path), "utf-8");
  15. //创建JXDocument对象
  16. JXDocument jxDocument = new JXDocument(document);
  17. //结合xpath语法查询
  18. List<JXNode> jxNodes = jxDocument.selN("//stu");
  19. for (JXNode jxNode : jxNodes) {
  20. System.out.println(jxNode);
  21. }
  22. }
  23. }
  24. //运行结果
  25. <stu number="stu_001">
  26. <name id="ideal">
  27. zhangsan
  28. </name>
  29. <age>
  30. 18
  31. </age>
  32. </stu>
  33. <stu number="stu_002">
  34. <name>
  35. lisi
  36. </name>
  37. <age>
  38. 30
  39. </age>
  40. </stu>
  1. //查询stu标签下的name标签
  2. List<JXNode> jxNodes = jxDocument.selN("//student/name");
  3. //查询stu标签下带有id属性且属性值ideal的name标签
  4. List<JXNode> jxNodes = jxDocument.selN("//stu/name[@id='ideal']");

结尾:

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

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

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

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

XML基础知识归纳(通俗易懂)的更多相关文章

  1. JavaEE XML 基础知识

    JavaEE XML 基础知识 @author ixenos 1.    XML开头都需要一个声明 <?和?>表明这是一个处理指令 <?xml version=”1.0” encod ...

  2. 对Linux(Unix)的基础知识归纳

    前言,不论是原生APP(Android&IOS),还是大型架构级基础环境(.NET&J2EE,或LAMP阵营等), 基本都不可避免的涉及到Linux(Unix),故还是觉得有必要把自己 ...

  3. .net学习笔记---xml基础知识

    一.XML简介 XML是一种标记语言,用于描述数据,它提供一种标准化的方式来来表示文本数据.XML文档以.xml为后缀.需要彻底注意的是XML是区分大小写的. 先从一个简单的XML例子来了解下xml基 ...

  4. XML基础知识-->Spring配置

    XML的特殊字符 XML中共有5个特殊的字符,分别是:&<>“’.如果配置文件中的注入值包括这些特殊字符,就需要进行特别处理.有两种解决方法:其一,采用本例中的<![CDAT ...

  5. JavaWeb基础: XML基础知识

    简介 XML:可扩展标记语言,W3C指定的用于描述结构化数据的语言,XML在实际开发中,经常用作软件的配置文件,以描述程序模块之间的依赖和组合关系. XML约束:XML常常用于软件配置管理,对于软件框 ...

  6. XML基础知识

    1.XML:(entension mark language) 可扩展的标记语言格式化的文本文件html(Hype Text Mark Language)(超文本标记语言)主要用于显示2.特点 一个良 ...

  7. XML基础知识学习

    概念: XML 指可扩展标记语言 XML 是一种标记语言,非常类似 HTML ,文本文件. XML 的设计宗旨是数据传输,而非显示数据 .存储和传输复杂的关系模型数据 XML 标签没有被提前定义 使用 ...

  8. XML -- XML基础知识

    1.XML的结构 XML的结构采用的是树结构,树结构就是一种一对多的关系结构. XML必定有一个根节点.因为,在解析这个XML时,需要有个起始位置进行遍历解析,这个跟节点就是起始位置. 2.XML的元 ...

  9. Java——XML基础知识

    XML大小写敏感,不可省略结束标签,可以标签自闭合<img />,属性值必须用引号括起来.CDATA部分用<![CDATA[ ]]>来限定界限,它们是字符数据的一种特殊形式.可 ...

随机推荐

  1. TensorFlow(二):基本概念以及练习

    一:基本概念 1.使用图(graphs)来表示计算任务 2.在被称之为会话(Session)的上下文(context)中执行图 3.使用tensor表示数据 4.通过变量(Variable)维护状态 ...

  2. 服务器之poll

    poll服务器方法采用将监听端口用数组存放起来,这样就不需要轮询的监听整个文件描述符了 #include <poll.h> int poll(struct pollfd *fds, nfd ...

  3. docker 笔记--运行中的容器如何添加端口映射

    解决: iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT_1} -j DNAT --to-destination ${CONTAINERIP}:$ ...

  4. oracle中时间格式时候的大于号是大于和等于的意思

    oracle中时间格式时候的大于号是大于和等于的意思

  5. Docker Dockerfile 定制镜像

    使用 Dockerfile 定制镜像  镜像的定制实际上就是定制每一层所添加的配置.文件.如果我们可以把每一层修改.安装.构建.操作的命令都写入一个脚本,用这个脚本来构建.定制镜像,那么无法重复的问题 ...

  6. What is the use of c# “Yield” keyword ?

    What is the use of c# “Yield” keyword ? “Yield keyword helps us to do custom stateful iteration over ...

  7. ftplib python ftp

    在气象领域,FTP是比较常用的一个数据来源.本文尝试采用python的ftplib包,实现了从指定ftp服务器中批量下载文件的功能.供大家学习参考. https://docs.python.org/3 ...

  8. SQL优化 | Oracle 绑定变量

    之前整理过一篇有关绑定变量的文章,不太详细,重新补充一下. Oracle 绑定变量 http://www.cndba.cn/Dave/article/1275 一.绑定变量 bind variable ...

  9. angular项目目录结构分析

    详情查看:https://www.angular.cn/guide/file-structure app.module.ts 定义 AppModule, 这个根模块会告诉 Angular 如何组装该应 ...

  10. IO流概述

    作用: 处理设备之间的数据传输的 I: Input(输入) , O: Output(输出) 什么是输入和输出? 我们说输入和输出问题是站在内存的角度而言 , 如果我们程序读取硬盘上的数据那么就是输入 ...