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 修饰的构造方法,如果手写构造方法,也必须是私有修饰的。而且构造方法必须写在常量的后面,这时最后一个常量就必须要写分号。
- 枚举中的常量名字大写,多个常量之间逗号分开,最后一个常量可以写分号,也可以不写。每一个常量,都表示这个类的对象。修饰符为
public enum TrafficLight {// 特殊的一种类 这种类 都继承 java.lang.Enum`类,是所有枚举的父类。
RED,GREEN,YELLOW
//枚举的本质是什么 符合一个类型的多个对象。
}
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 枚举的使用
由于枚举的常量为静态修饰可以直接枚举名.调用
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);
}
}
}
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 version="1.0" encoding="UTF-8"?>
<persons>
<person id="p001">
<name>张三</name>
</person>
<person id="p002">
<name>李四</name>
</person>
</persons>
类似于 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 version="1.0" encoding="UTF-8"?>
<beans>
<bean className="com.itheima.bean.User">
<property name="username" value="jack"></property>
</bean>
</beans>
类似于 java 代码:
class User{
private String username;
private String pws;
//补全set\get方法
}
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 文档声明格式:
<?xml version="1.0" encoding="UTF-8"?>
- 文档声明必须为
<?xml开头,以?>
结束; - 文档声明必须从文档的 0 行 0 列位置开始;
- 文档声明只有 2 个属性:
1. version:指定XML文档版本。必须属性,因为我们不会选择1.1,只会选择1.0;
2. encoding:指定当前文档的编码。可选属性,默认值是utf-8;
元素
- 元素 element
<bean></bean>
- 元素是 XML 文档中最重要的组成部分,
- 普通元素的结构开始标签、元素体、结束标签组成。例如:
- 元素体:元素体可以是元素,也可以是文本,例如:你好
- 空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:
- 元素命名:
1. 区分大小写
2. 不能使用空格,不能使用冒号:
3. 不建议以XML、xml、Xml开头
格式化良好的 XML 文档,必须只有一个根元素。
属性
- 属性 attribute
<bean id="" className="">
- 属性是元素的一部分,它必须出现在元素的开始标签中
- 属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
- 一个元素可以有 0~N 个属性,但一个元素中不能出现同名属性
- 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
注释
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。
<?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 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 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 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 文档。
声明命名空间
默认命名空间:<xxx xmlns=””>,使用<标签>
显式命名空间:<xxx xmlns:别名=””>,使用<别名:标签>
第四章 XML 解析
4.1 xml 解析概述
当将数据存储在 XML 后,我们就希望通过程序获得 XML 的内容。如果我们使用 Java 基础所学习的 IO 知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作 XML。
4.2 常见的解析方式和解析器
开发中比较常见的解析方式有三种,如下:
- DOM:要求解析器把整个 XML 文档装载到内存,并解析成一个 Document 对象。
优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
缺点:XML文档过大,可能出现内存溢出。
- SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)
优点:处理速度快,可以处理大文件
缺点:只能读,逐行后将释放资源。
- PULL:Android 内置的 XML 解析方式,类似 SAX。(了解)
解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。
4.3 dom 解析原理和结构模型
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 如下:
SaxReader 对象
read(…) 加载执行xml文档
Document 对象
getRootElement() 获得根元素
Element 对象
elements(…) 获得指定名称的所有子元素。可以不指定名称 element(…) 获得指定名称第一个子元素。可以不指定名称 getName() 获得当前元素的元素名 attributeValue(…) 获得指定属性名的属性值 elementText(…) 获得指定名称子元素的文本值 getText() 获得当前元素的文本内容
API 案例实现
编写 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>
编写解析 xml 代码:
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);
}
}
}