Skip to content

day16【枚举、xml、综合案例】

今日内容

  • 枚举
  • xml 文档
  • DTD 约束
  • Schema 约束
  • DOM 解析

教学目标

  • [ ] 能够自定义枚举常量
  • [ ] 能够说出 XML 的作用
  • [ ] 了解 XML 的组成元素
  • [ ] 能够说出有哪些 XML 约束技术
  • [ ] 能够说出解析 XML 文档 DOM 方式原理
  • [ ] 能够通过 Dom4j 解析 XML 文档

第一章 枚举

1.1 枚举概述

枚举类: 如果一个类只有固定的几个对象,且对象的内容不可改变.

jdk1.5 发现有好多这样的类,于是把这样的类称为 “枚举类”,并且给它们赋予了新的定义格式!!

枚举是 JDK1.5 新增的引用数据类型,和类,接口是一个级别的,定义枚举的关键字为enum

java.lang.Enum类,是所有枚举的父类。

枚举的本质就是一个类的多个对象。

1.2 枚举的定义

  • 格式:public enmu 枚举名{}
  • 枚举常量定义:
    • 枚举中的常量名字大写,多个常量之间逗号分开,最后一个常量可以写分号,也可以不写。每一个常量,都表示这个类的对象。修饰符为public static final
    • 枚举中有默认的无参数的 private 修饰的构造方法,如果手写构造方法,也必须是私有修饰的。而且构造方法必须写在常量的后面,这时最后一个常量就必须要写分号。
java
public enum TrafficLight {// 特殊的一种类   这种类 都继承 java.lang.Enum`类,是所有枚举的父类。
    RED,GREEN,YELLOW

    //枚举的本质是什么  符合一个类型的多个对象。
}
java
package com.itheima.enum02;

public enum TrafficLight {// 特殊的一种类   这种类 都继承 java.lang.Enum`类,是所有枚举的父类。

    RED("red"),GREEN("green"),YELLOW("yellow");
   //这三个常量是 举例子的 意思 该交通灯只有 三个对象
    // 它们现在用的是默认的构造 无参
    //有带参的了 name RED就带参数
    //枚举的本质是什么  符合一个类型的多个对象。


    private String color;
    // 不让外界 去搞
    private TrafficLight(String color){
        this.color=color;
    }


    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

}

1.3 枚举的使用

由于枚举的常量为静态修饰可以直接枚举名.调用

java
package com.itheima.enum02;

public class Demo {

    public static void main(String[] args) {
        TrafficLight red = TrafficLight.RED;

        System.out.println(red);//red.toString()
        System.out.println(red.name());//获取到 枚举常量的名字

        System.out.println(red.getColor());//枚举是不是一个对象 所以可以调用对象中方法


        TrafficLight[] values = TrafficLight.values();//获取该枚举的所有的对象

        System.out.println(values.length);

        for (TrafficLight value : values) {

            System.out.println(value);
        }
    }
}

1642388238223

1642388294079

1.4 枚举使用建议

  • 当你需要定义一组常量时,可以使用枚举类型。

  • 尽量不要使用枚举的高级特性,事实上高级特性都可以使用普通类替换,没有必要引入枚举,反而增加了程序的复杂性,不符合开发原则。

    比如 定义季节---四个季节对象

    ​ 定义星期类 七个星期对象

第二章 XML

2.1 xml 概述

什么是 XML

  • XML :可扩展标记语言(EXtensible Markup Language

    XML 它是一种标记语言 由标签组成的。

    什么是标签呢? 由尖括号组成的 元素

    java
    <apple></apple>双标签
    <banana/> 单标签

    语言:代码有语法性。

    可扩展---相对于 html 来说:

    html 标签都是提前定义好的,有一定的含义。

    ​ xml 标签是自定义,之前没有定义好,自己去定义。

  • W3C 在 1998 年 2 月发布 1.0 版本,2004 年 2 月又发布 1.1 版本,单因为 1.1 版本不能向下兼容 1.0 版本,所以 1.1 没有人用。同时,在 2004 年 2 月 W3C 又发布了 1.0 版本的第三版。我们要学习的还是 1.0 版本。

XML 与 HTML 的主要差异

  • xml 标签都是自定义的,html 标签是预定义。
  • xml 的语法严格,html 语法松散。
  • xml 是存储数据的,html 是展示数据。
  • Properties 存储数据形式单一,且只能在 java 语言中使用
  • xml 存储数据形式很丰富,其它编程语言也可以使用 xml 存储数据

xml 的作用

  • 存放数据
xml
<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person id="p001">
		<name>张三</name>
	</person>
	<person id="p002">
		<name>李四</name>
	</person>
</persons>

类似于 Java 代码:

java
class Person{
	String id;
	String name;
}

public void test(){
	HashSet<Person> persons = new HashSet<Person>();
	persons.add( new Person("p001","张三") );
	persons.add( new Person("p002","李四") );
}
  • 配置文件
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean className="com.itheima.bean.User">
		<property name="username" value="jack"></property>
	</bean>
</beans>

类似于 java 代码:

java
class User{
	private String username;
	private String pws;
	//补全set\get方法
}
java
public static void main(String[] args){
    Class clzzz = Class.forName("com.itheima.bean.User");
    Object obj = clazz.newInstance();
    Method method = clazz.getMethod("setUsername",String.class);
    method.invoke(obj,"jack");
}

2.2 xml 的组成元素

xml 必须进行文档声明,才能证明它是 xml.

文档声明

  • XML 文档声明格式:
java
<?xml version="1.0" encoding="UTF-8"?>
  1. 文档声明必须为<?xml开头,以?>结束;
  2. 文档声明必须从文档的 0 行 0 列位置开始;
  3. 文档声明只有 2 个属性:
properties
1. version:指定XML文档版本。必须属性,因为我们不会选择1.1,只会选择1.0;
2. encoding:指定当前文档的编码。可选属性,默认值是utf-8;

元素

  • 元素 element
xml
<bean></bean>
  1. 元素是 XML 文档中最重要的组成部分,
  2. 普通元素的结构开始标签、元素体、结束标签组成。例如:
  3. 元素体:元素体可以是元素,也可以是文本,例如:你好
  4. 空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:
  5. 元素命名:
properties
1. 区分大小写
2. 不能使用空格,不能使用冒号:
3. 不建议以XML、xml、Xml开头

格式化良好的 XML 文档,必须只有一个根元素。

属性

  • 属性 attribute
xml
<bean id="" className="">
  1. 属性是元素的一部分,它必须出现在元素的开始标签中
  2. 属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
  3. 一个元素可以有 0~N 个属性,但一个元素中不能出现同名属性
  4. 属性名不能使用空格、冒号等特殊字符,且必须以字母开头

注释

XML 的注释,以“”结束。注释内容会被 XML 解析器忽略!

转义字符

因为很多符号已经被 XML 文档结构所使用,所以在元素体或属性值中想使用这些符号就必须使用转义字符,例如:“<”、“>”、“’”、“””、“&”

第三章 XML 约束

用于约束 xml 的文件,叫约束文件,用于约束 xml 的语法,xml 约束语法。

在 XML 技术里,可以编写一个文档来约束一个 XML 文档的书写规范,这称之为 XML 约束。 常见的 xml 约束:DTD、Schema

我们对于约束的要求是,能看懂就看懂,看不懂也没事,最主要的是我们 xml 被约束以后,不写错误操作即可。

3.1 DTD 约束

什么是 DTD

DTD(Document Type Definition),文档类型定义,用来约束 XML 文档。

规定 XML 文档中元素的名称,子元素的名称及顺序,元素的属性等。

DTD 重点要求

开发中,我们很少自己编写 DTD 约束文档,通常情况我们都是通过框架提供的 DTD 约束文档,编写对应的 XML 文档。常见框架使用 DTD 约束有:SpringMVC、MyBatis 等。

通过提供的 DTD“bean.dtd”编写 XML。

java
<?xml version="1.0" encoding="UTF-8"?>
<!--
	传智播客DTD教学实例文档。
	模拟spring规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
	格式如下:
	<!DOCTYPE beans SYSTEM "bean.dtd">
-->
<!ELEMENT beans (bean*,import*) >
<!ELEMENT bean (property*)>
<!ELEMENT property (#PCDATA)>

<!ELEMENT import (#PCDATA)>

<!ATTLIST bean id CDATA #REQUIRED
			   className CDATA #REQUIRED
>

<!ATTLIST property name CDATA #REQUIRED
				   value CDATA #REQUIRED
>

<!ATTLIST import resource CDATA #REQUIRED>

案例实现

完成 xml 内容编写:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans SYSTEM "bean.dtd">
<beans>
	<bean id="" className=""></bean>

	<bean id="" className="">
		<property name="" value=""></property>
		<property name="" value=""></property>
	</bean>

	<import resource=""></import>
	<import resource=""></import>

</beans>

3.2 Schema 约束

什么是 Schema

Schema 是新的 XML 文档约束; Schema 要比 DTD 强大很多,是 DTD 替代者; Schema 本身也是 XML 文档,但 Schema 文档的扩展名为 xsd,而不是 xml。 Schema 功能更强大,数据类型更完善 Schema 支持名称空间

Schema 重点要求

与 DTD 一样,要求可以通过 schema 约束文档编写 xml 文档。常见框架使用 schema 的有:Spring 等

通过提供“bean-schema.xsd”编写 xml 文档

xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
	传智播客Schema教学实例文档。
	模拟spring规范,如果开发人员需要在xml使用当前Schema约束,必须包括指定命名空间。
	格式如下:
	<beans xmlns="http://www.itcast.cn/bean"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.itcast.cn/bean bean-schema.xsd"
	>
-->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
		targetNamespace="http://www.itcast.cn/bean"
		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		xmlns:tns="http://www.itcast.cn/bean"
		elementFormDefault="qualified">
	<!-- 声明根标签 -->
	<element name="beans">
		<complexType>
			<choice minOccurs="0" maxOccurs="unbounded">
				<element name="bean">
					<complexType>
						<sequence minOccurs="0" maxOccurs="unbounded">
							<element name="property">
								<complexType>
									<attribute name="name" use="required"></attribute>
									<attribute name="value" use="required"></attribute>
								</complexType>
							</element>
						</sequence>
						<attribute name="id" use="required"></attribute>
						<attribute name="className" use="required"></attribute>
					</complexType>
				</element>
				<element name="import">
					<complexType>
						<attribute name="resource" use="required"></attribute>
					</complexType>
				</element>
			</choice>
		</complexType>
	</element>
</schema>

案例实现

完成 xml 内容编写

xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.itcast.cn/bean"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.itcast.cn/bean bean-schema.xsd"
>
	<bean id="" className=""></bean>
	<bean id="" className="">
		<property name="" value=""/>
		<property name="" value=""/>
	</bean>

	<import resource=""/>
	<import resource=""/>
</beans>

3.3 命名空间(语法)

什么是命名空间

如果一个 XML 文档中使用多个 Schema 文件,而这些 Schema 文件中定义了相同名称的元素时就会出现名字冲突。这就像一个 Java 文件中使用了 import java.util.*和 import java.sql.*时,在使用 Date 类时,那么就不明确 Date 是哪个包下的 Date 了。

总之名称空间就是用来处理元素和属性的名称冲突问题,与 Java 中的包是同一用途。如果每个元素和属性都有自己的名称空间,那么就不会出现名字冲突问题,就像是每个类都有自己所在的包一样,那么类名就不会出现冲突。

约束文档和 xml 关系

当 W3C 提出 Schema 约束规范时,就提供“官方约束文档”。我们通过官方文档,必须“自定义 schema 约束文档”,开发中“自定义文档”由框架编写者提供。我们提供“自定义文档”限定,编写出自己的 xml 文档。

声明命名空间

xml
默认命名空间:<xxx xmlns=””>,使用<标签>
显式命名空间:<xxx xmlns:别名=””>,使用<别名:标签>

第四章 XML 解析

4.1 xml 解析概述

当将数据存储在 XML 后,我们就希望通过程序获得 XML 的内容。如果我们使用 Java 基础所学习的 IO 知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作 XML。

4.2 常见的解析方式和解析器

  • 开发中比较常见的解析方式有三种,如下:
    • DOM:要求解析器把整个 XML 文档装载到内存,并解析成一个 Document 对象。
properties
优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
缺点:XML文档过大,可能出现内存溢出。
  • SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)
properties
优点:处理速度快,可以处理大文件
缺点:只能读,逐行后将释放资源。
  • PULL:Android 内置的 XML 解析方式,类似 SAX。(了解)

解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。

4.3 dom 解析原理和结构模型

1642220864541

XML DOM 将整个 XML 文档加载到内存,生成一个 DOM 树,并获得一个 Document 对象,通过 Document 对象就可以对 DOM 进行操作。

DOM 中的核心概念就是节点,在 XML 文档中的元素、属性、文本等,在 DOM 中都是节点!

4.4 API 使用

DOM4J 是一个 Java 的 XML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过 sun 公司官方的 dom 技术,如今可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML。

导包 导包 导包 导包

如果想要使用 DOM4J,需要引入支持 xpath 的 jar 包 dom4j-1.6.1.jar

DOM4J 必须使用核心类 SaxReader 加载 xml 文档获得 Document,通过 Document 对象获得文档的根元素,然后就可以操作了。

常用 API 如下:

  1. SaxReader 对象
    read(…) 加载执行xml文档
  2. Document 对象

    getRootElement() 获得根元素
  3. Element 对象

    elements(…) 获得指定名称的所有子元素。可以不指定名称
    element(…) 获得指定名称第一个子元素。可以不指定名称
    getName() 获得当前元素的元素名
    attributeValue(…) 获得指定属性名的属性值
    elementText(…) 获得指定名称子元素的文本值
    getText() 获得当前元素的文本内容

API 案例实现

1642220834874

编写 xml 文件:

xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--其实这里是由约束-->
<configuration>
    <environments default="development">
        <environment id="development">
            <!--数据库事务管理器  JDBC
            -->
            <transactionManager type="JDBC"/>
            <!--mybatis连接池 的四个属性信息-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--  sql语句的位置 操作数据库的语句写在哪里? -->
    <mappers>
        <mapper resource="com\itheima\mapper\UserMapper.xml"/>
        <mapper resource="com\itheima\mapper\PersonMapper.xml"></mapper>
    </mappers>
</configuration>

1642387820630

编写解析 xml 代码:

java
package com.itheima.parseXml;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

/*
     需求
       请你使用dom解析方式 解析  mybatis-config.xml文件
         我们想要的 是 已经在图 红圈标出来了

         DOM 刚开始 是一个dom书

         1: 需要借助 一些api 完成
           将我们day16\\src\\mybatis-config.xml
           文件 转换成 Doucment对象。
           需要 读取文件的流。
           SAXReader reader = new SAXReader();
        2:如果有了   Doucment对象。
            Doucment document = reader.read("xml文件的路径即可");
        3: 根据api获取根元素  document.getRootElement()  获取根元素
        4: 获取名字叫 evironments子元素   根元素 是 Element类型   根元素.element("子元素名称") 获取到元素的指定子元素
        5: 根据  evironments元素 的子元素 evironment
        6: 根据  evironment元素 的子元素 transctionManageer
        7: 找到这个元素 解析它的 type属性  获取值 输出。 解析某个元素的某个属性  元素.attributeValue(属性名)
        8: 根据  evironment元素 的子元素 dataSource
        9: 根据  dataSource 元素 获取 多个 property元素。    元素.elements("子元素名称") 获取某个元素多个执行的子元素
        10: 遍历得到每一个  property 然后解析里面
            name 属性 和 value属性  并输出
        11:根据根元素 找到 mappers元素
        12:根据mappers找到 mapper元素们
           遍历  得到每个mapper  解析 resource属性 完成输出
 */
public class ParseXml {

    public static void main(String[] args) throws Exception{
        //1:获取DOM4J中提供的 一个流对象
        SAXReader reader = new SAXReader();
        //2: 根据流 读取 xml文件
        Document document = reader.read("day16\\src\\mybatis-config.xml");

        //3: 根据api获取根元素  document.getRootElement()
        Element rootElement = document.getRootElement();
        //4: 获取名字叫 evironments子元素
        Element environments = rootElement.element("environments");
        //5:根据  evironments元素 的子元素 evironment
        Element environment = environments.element("environment");
        //6:根据  evironment元素 的子元素 transactionManager
        Element transactionManager = environment.element("transactionManager");
        //7: 找到这个元素 解析它的 type属性
        String type = transactionManager.attributeValue("type");
        System.out.println("数据库事务管理器是:"+type);
       //8  根据  evironment元素 的子元素 dataSource
        Element dataSource = environment.element("dataSource");
        // 9: 根据  dataSource元素获取 多个property
        List<Element> properties = dataSource.elements("property");
        //10: 解析每一个
        System.out.println("解析数据库的四个配置信息是:");
        for (Element property : properties) {
            //解析  name="driver" value="com.mysql.jdbc.Driver"
            String name = property.attributeValue("name");
            String value = property.attributeValue("value");
            System.out.println(name+":"+value);
        }
        //11: 根据根元素 找到 mappers元素
        Element mappers = rootElement.element("mappers");
        //12:找mappers里面的mapper们
        List<Element> mapperList = mappers.elements("mapper");
        for (Element mapper : mapperList) {
            //解析里面的 resource="com\itheima\mapper\PersonMapper.xml"
            String resource = mapper.attributeValue("resource");
            System.out.println("sql语句的位置:"+resource);
        }
    }
}

Released under the MIT License.