什么是XML

碎碎念

很老之前的笔记了,而且xml现在基本上淘汰了,现在网络传输的主流媒介是JSON
但感觉还不错就保留了说不定以后用得上(不太可能)

XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。

可扩展标记语言指的是标签可以自由定义,可以用于自定义数据格式

XML的几个特点和使用场景

特点:

  • 一是纯文本,默认使用UTF-8编码;
  • 二是可嵌套;
    如果把XML内容存为文件,那么它就是一个XML文件。
    XML的使用场景:
  • XML内容经常被当成消息进行网络传输
  • 作为配置文件用于存储系统的信息。 例如

XML的语法规则

  1. XML文件的后缀名为:xml
  2. 文档声明必须是第一行
  3. XML的标签(元素)规则:
    1. 标签由一对尖括号和合法标识符组成: <name></name>必须存在一个根标签,有且只能有一个。
    2. 标签必须成对出现,有开始,有结束: <name></name>
    3. 特殊的标签可以不成对,但是必须有结束标记,如:<br/>
    4. 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来<student id = “1”></name>
    5. 标签需要正确的嵌套
  4. XML的其他组成:
    1. XML文件中可以定义注释信息:<!– 注释内容 -->
    2. XML文件中可以存在以下特殊字符

    1. XML文件中可以存在CDATA区: <![CDATA[ …内容… ]]>

    XML解析式可能发生冲突,例如自定义的sql标签里存储SQL语句:

    1. 可以用特殊字符替代冲突的符号;
    2. 或者使用CDATA区,在里边书写包含特殊字符内容
      【IDEA中输入CD会智能提示;浏览器不能解析,但后面用到的技术可以去掉CDATA区】

XML文档约束

由于XML文件可以自定义标签,导致XML文件可以随意定义,程序在解析的时候可能出现问题。所以我们需要对XML文档进行约束。
文档约束:用来限定xml文件中的标签以及属性应该怎么写。→以此强制约束程序员必须按照文档约束的规定来编写xml文件。
文档约束有两种方式:DTD和schema,如下

  1. DTD

    1. 编写DTD约束文档,后缀必须是.dtd

    2. 在需要编写的XML文件中导入该DTD约束文档

    3. 按照约束的规定编写XML文件的内容。

  2. schema

    1. 编写schema约束文档,后缀必须是.xsd

    2. 在需要编写的XML文件中导入该schema约束文档

    3. 按照约束内容编写XML文件的标签。

两者的比较:

  1. XML的文档约束-DTD的作用和问题?
    • 可以约束XML文件的编写。
    • 不能约束具体的数据类型。
  2. XML的文档约束-schema的优点?
    • 可以约束XML文件的标签内容格式,以及具体的数据类型。
    • 本身也是xml文件,格式更严谨。【虽然后缀不一样但数据内容式是xml的语法格式】

XML如何解析

什么是XML解析:使用程序读取XML中的数据

两种解析方式:SAX和DOM解析

SAX解析【逐行解析——前端(略)】

DOM解析

DOM解析解析文档对象模型

DOM解析即树状解析,将对象以树的形态整体解析出来,且每个对象结点都实现了Node接口

Dom常见的解析工具

名称 说明
JAXP SUN公司提供的一套XML的解析的API
JDOM JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。
dom4j 是JDOM的升级品,用来读写XML文件的。具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom 技术,同时它也是一个开放源代码的软件,Hibernate也用它来读写配置文件。
jsoup 功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便

如何使用Dom4J解析XML文件

Dom4J的解析思想:得到文档对象Document,从中获取元素对象和内容。
Dom4J的解析后的数据形式:通常数据会封装成Java的对象,如单个对象,或者集合对象形式

但在此之前我们需要先创建Dom4J的解析器对象

基本步骤

  1. 在项目中导入Dom4J框架
    1. 下载Dom4j框架,官网下载。
    2. 在项目中创建一个文件夹:lib
    3. 将dom4j-2.1.1.jar文件复制到 lib 文件夹
    4. 在jar文件上点右键,选择 Add as Library -> 点击OK
    5. 在类中导包使用
  2. 创建Dom4J的解析器对象
  3. 加载XML文件成为Document对象
  4. 获取Document对象的根元素对象
  5. 进一步解析XML的其它元素、属性、文本

Dom4J框架解析元素的类和方法

根据需求驱动来记就好

SAXReader类

构造器/方法 说明
public SAXReader() 创建Dom4J的解析器对象
Document read(String url) 加载XML文件成为Document对象

Document类

方法名 说明
Element getRootElement() 获得根元素对象

Node类

方法名 说明
List<Element> elements() 得到当前元素下所有子元素
List<Element> elements(String name) 得到当前元素下指定名字的子元素返回集合
Element element(String name) 得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个
String getName() 得到元素名字
String attributeValue(String name) 通过属性名直接得到属性值
String elementText(子元素名) 得到指定名称的子元素的文本
String getText() 得到文本

对于获取Text的方法后面加上Trim可以获得不带格式(空格)的文本信息

Dom4J解析XML应用实例

应用场景:
利用Dom4J的知识,将Contact.xml文件中的联系人数据封装成List集合,其中每个元素是实体类Contact。打印输出 List 中的每个元素。
效果图:

步骤:

  1. 首先是准备待解析的Contact.xml文件
  2. 根据待解析的Contact.xml文件创建Contact标准实体类
public class Contact {
    private String name;
    private int id;
    private boolean vip;
    private char gender;
    private String email;

    public Contact() {
    }

    public Contact(String name, int id, boolean vip, char gendar, String email) {
        this.name = name;
        this.id = id;
        this.vip = vip;
        this.gender = gendar;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isVip() {
        return vip;
    }

    public void setVip(boolean vip) {
        this.vip = vip;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", vip=" + vip +
                ", gendar=" + gender +
                ", email='" + email + '\'' +
                '}';
    }
}
  1. 在测试类中编写解析XML文件和打印数据的核心逻辑
public class Dom4JTest2 {
    @Test
    public void parseToList() throws Exception {
        // 需求:解析XML中的数据成为一个List集合对象。
        // 1、导入框架(做过)
        // 2、创建SaxReader对象
        SAXReader saxReader = new SAXReader();
        // 3、加载XML文件成为文档对象Document对象。
        Document document =
                saxReader.read(Dom4JTest2.class.getResourceAsStream("/Contacts.xml"));
        // 4、先拿根元素
        Element root = document.getRootElement();
        // 5、提取contact子元素
        List<Element> contactEles = root.elements("contact");
        // 6、准备一个ArrayList集合封装联系人信息
        List<Contact> contacts = new ArrayList<>();
        // 7、遍历Contact子元素
        for (Element contactEle : contactEles) {
            // 8、每个子元素都是一个联系人对象
            Contact contact = new Contact();
            contact.setId(Integer.valueOf(contactEle.attributeValue("id")));
            contact.setVip(Boolean.valueOf(contactEle.attributeValue("vip")));
            contact.setName(contactEle.elementTextTrim("name"));
            contact.setGender(contactEle.elementTextTrim("gender").charAt(0));
            contact.setEmail(contactEle.elementText("email"));
            // 9、把联系人对象数据加入到List集合
            contacts.add(contact);
        }
        // 10、遍历List集合
        for (Contact contact : contacts) {
            System.out.println(contact);
        }
    }
}

Xpath——XML检索技术

什么是Xpath检索技术

首先Dom4j需要进行文件的全部解析,然后再寻找数据。而Xpath技术更加适合做信息检索【推荐检索数据】。
XPath使用路径表达式来定位XML文档中的元素节点或属性节点。

怎么使用Xpath检索技术

需求: 使用Dom4J把一个XML文件的数据进行解析
分析:

  1. 导入jar包(dom4j和jaxen-1.1.2.jar),Xpath技术依赖Dom4j技术

  2. 通过dom4j的SAXReader获取Document对象

  3. 利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作。

    方法名 说明
    Node selectSingleNode("表达式") 获取符合表达式的唯一元素
    List<Node> selectNodes("表达式") 获取符合表达式的元素集合

XPath提供的四种检索数据的写法:

  1. 绝对路径: /根元素/子元素/子元素。
  2. 相对路径: ./子元素/子元素。 (.代表了当前元素)
  3. 全文搜索:
    • //元素 在全文找这个元素
    • //元素1/元素2 在全文找元素1下面的一级元素2
    • //元素1//元素2 在全文找元素1下面的全部元素2
  4. 属性查找。
    • //@属性名称 在全文检索属性对象。
    • //元素[@属性名称] 在全文检索包含该属性的元素对象。
    • //元素[@属性名称=值] 在全文检索包含该属性的元素且属性值为该值的元素对象。