07-XML、Dom4j、设计模式
1、XML
1.1、XML概念
-
XML全程为(eXtensible Markup Language),是一种可扩展的标记语言
- 标记语言
- 通过标签来描述数据的一门语言
- 可扩展
- 标签的名字是可以自定义的
- 标记语言
-
demo
-
<person id="1" color="yellow"> <name>武松</name> <age>18</age> <email>panpan@163.com</email> </person>
-
1.2、XML的作用
- XML被设计用来存储和传输数据
1.3、XML组成
1.3.1、文档声明
-
文档声明格式
-
XML文件的后缀名
- .xml
-
文档声明必须是XML第一行
-
demo
-
<?xml version="1.0" encoding="UTF-8" ?> <!-- verson:版本号,该属性是必须存在的 encoding:文件编码,该属性不是必须存在的(一般都取值为UTF-8) -->
-
-
-
文档声明作用
- 告诉别人这是一个XML文件
1.3.2、标签和属性
- 标签概念
- 标签也称为元素
- 注意事项
- 标签由一堆尖括号和合法标识符组成
-
- 标签必须成对出现
张三
- 没有内容的标签可以提前结束
- 标签由一堆尖括号和合法标识符组成
- 属性概念
- 定义在开始标签内的内容
- 注意事项
- 标签中可以定义属性,属性和标签名空格隔开
-
- 属性值必须用引号引起来
- 标签中可以定义属性,属性和标签名空格隔开
1.3.3、根标签
- 没有被其他标签包裹的就称为根标签
- 在一个XML文档中,只允许由一个根标签
1.3.4、注释
- 注释语法格式
- 注释作用
- 给程序员看的
1.3.5、实体字符/转义字符
- 实体字符
1.3.6、字符数据区
- CDATA字符数据区的作用
- 放在CDATA字符数据区中的数据,作为纯文本解析,原样显示
- 快捷键
- CD
1.4、XML约束
1.4.1、DTD结束
- DTD约束作用
- 比较简单,功能相对弱
- 导入DTD文件的两种格式
- 本地的约束
- 适合个人,公司小范围的使用
- 网络上的约束
- 适合大范围的使用
- 本地的约束
- demo
- DTD使用案例
- 步骤
- 赋值bookshelf.dtd到模块中
- 新建books.xml
- 在books.xml中导入bookshelf.dtd约束
- 编写XML
- 步骤
1.4.2、Schema约束
-
Schema约束作用
- 比较复杂,功能相对较强
-
Schema概述
- Schema功能强大,数据类型约束更完善
- Schema文件本身也是XML文件
- 一个XML文件中可以引入多个Schema约束文件
- Schema约束文件的扩展名:.xsd
-
Schema约束导入格式
-
<根标签 xmlns="命名空间" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="命名空间 schema约束文件名"> <!-- 编写XML元素 --> </根标签>
-
-
demo
2、dom4j
2.1、XML解析
- XML解析概念
- 使用程序读取XML中的数据
- DOM解析原理
- 一次性读取XML中的所有数据,在内存中行程一颗DOM树
- DOM树demo
- 两种解析方式
- SAX解析
- DOM解析
- 常用的解析工具介绍
- JAXP
- SUN公司提供的一套XML的解析的API
- JDOM
- JDOM是一个开源项目,它基于树形结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化及多种操作
- dom4j
- dom4j是JDOM的升级品,用来读写XML文件的。具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,Hibernate也用它来读写配置文件
- jsoup
- jsoup是一个功能强大的DOM方式的XML解析开发包,尤其对HTML解析更加方便
- JAXP
2.2、dom4j下载和导入
- 下载
- Dom4j官网地址: http://www.dom4j.org/
- 导入步骤
- 在项目中创建一个文件夹:lib
- 将dom4j-2.1.1.jar文件复制到lib文件夹
- 在jar文件上点右键,选择 Add as Library -> 点击OK
- 在类中导包使用
2.3、dom4j解析XML-得到Document对象
- SAXReader对象
- SAXReader()
- 创建解析器
- Document read(String url)
- 加载执行XML文档
- SAXReader()
- Ducument对象
- Element getRootElement()
- 获得根元素
- Element getRootElement()
2.4、dom4j解析XML-Element
-
dom4j解析XML-Element
-
- List elements()得到当前元素下所有子元素
- List elements(String name)得到当前元素下指定名字的子元素返回集合
- Element element(String name)得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个
- String getName()得到元素名字
- String attributeValue(String name)通过属性名直接得到属性值
- String elementText(子元素名)得到指定名称的子元素的文本
- String getText()得到文本
-
2.5、XML解析案例
-
步骤
- 1.定义一个类,用来保存每一个元素中的信息
- 2.创建解析器
- 3.解析XML
- 4.得到根标签
- 5.得到所有的特定子标签
- 6.创建集合保存子标签中的元素信息
- 7.遍历标签中的所有元素信息
- 8.根据数据创建类对象
- 9.遍历集合
-
demo
-
// 1.创建解析器 SAXReader saxReader = new SAXReader(); // 2.使用解析器解析XML File file = new File("study_day14\\src\\com\\itheima\\demo01XML解析案例\\Contact.xml"); Document document = saxReader.read(file); // getRootElement: 获取根元素 Element rootElement = document.getRootElement(); // getName(): 获取元素名称 String rootName = rootElement.getName(); System.out.println("rootName = " + rootName); // elements(): 获取所有子元素 // List<Element> elements = rootElement.elements(); // elements(name): 获取所有指定名称的子元素 List<Element> elements = rootElement.elements("contact"); ArrayList<Contact> list = new ArrayList<>(); for (Element element : elements) { String idStr = element.attributeValue("id"); String vipStr = element.attributeValue("vip"); String name = element.elementText("name"); String gender = element.elementText("gender"); String email = element.elementText("email"); int id = Integer.parseInt(idStr); boolean vip = Boolean.getBoolean(vipStr); Contact contact = new Contact(id , vip , name , gender , email); list.add(contact); } // element(name): 获取一个子元素,如果有多个返回第一个 // elementText(子元素): 得到子元素的值 for (Contact contact : list) { System.out.println(contact); }
-
2.6、XPath
2.6.1、XPath介绍
- 概念
- XPath使用路径表达式来选取XML文档中的元素节点或属性节点。节点是通过沿着路径(path)来选取的。XPath在解析XML文档方面提供了独树一帜的路径思想
- Document中和XPath相关的API
- Node selectSingleNode("表达式")
- 获取符合表达式的唯一元素
- List selectNodes("表达式")
- 获取符合表达式的元素集合
- Node selectSingleNode("表达式")
2.6.2、XPath绝对路径
- 方法
- /根元素/子元素/孙元素
- 从根元素开始,一级一级往下查找,不能跨级
- /根元素/子元素/孙元素
2.6.3、XPath相对路径
- 方法
- ./子元素/孙元素
- 从当前元素开始,一级一级向下查找,不能跨级
- ./子元素/孙元素
2.6.4、XPath全文搜索
- 需求
- 直接全文搜索所有的name元素并打印
- 创建XPath表达式
- 调用Document对象的selectNodes()方法执行XPath获得节点
- 直接全文搜索所有的name元素并打印
- 方法
- //contact
- 找contact元素,无论元素在哪里
- //contact/name
- 找contact,无论在哪一级,但name一定是contact的子节点
- //contact//name
- contact无论在哪一级,name只要是contact的子孙元素都可以找到
- //contact
2.6.5、XPath属性查找
- 方法
- //@属性名
- 查找属性对象,无论是哪个元素,只要有这个属性即可
- //元素[@属性名]
- 查找元素对象,全文搜索指定元素名和属性名
- //元素[@属性名='值']
- 查找元素对象,全文搜索指定元素名和属性名,并且属性值相等
- //@属性名
3、工厂模式
3.1、概念
- 工厂设计模式(Factory Pattern)是Java中最常用的设计模式之一。通过专门定义一个类来负责创建其他类的实例
3.2、工厂模式的作用
- 解决类于类之间的耦合问题,屏蔽了外界对具体类的依赖,让类的创建更加简单
3.3、工厂模式实现步骤
- 1.编写一个Car接口,提供run方法
- 2.编写一个Benz类实现Car接口,重写run方法
- 3.编写一个Bmw类实现Car接口,重写run方法
- 4.提供一个CarFactory(汽车工厂),用于生产汽车对象
- 定义CarFactoryTest测试汽车工厂
4、单例模式
4.1、单例概述
- 单例模式,是一种常用的软件设计模式
4.2、单例的作用
- 通过单例模式可以保证系统中,应用该模式的这个类永远只有一个实例。节省内存空间
4.3、单例设计模式的分类
4.3.1、饿汉式单例设计模式
-
饿汉式单例
-
饿汉式单例设计模式
- 在使用单例对象时候,对象已经提前创建好了
-
饿汉式单例设计模式实现步骤
- 1.将构造器私有
- 2.使用成员变量保存创建好的单例对象
- 3.提供一个方法返回单例对象给别人使用
-
代码示例
-
public class AudioPlayer { // private int a = 10; private AudioPlayer() {} // 这个对象是在类加载的时候进行创建的 private static final AudioPlayer instance = new AudioPlayer(); // 提供公共的访问方式 public static AudioPlayer getInstance(){ return instance; } }
-
-
4.3.2、懒汉式单例设计模式
-
概念
- 在真正需要该对象的时候,才去创建一个对象(延迟加载对象)
-
懒汉式单例设计模式实现步骤
- 1.将构造器私有
- 2.使用成员变量保存单例对象
- 3.提供一个方法创建并返回单例对象
-
代码示例
-
public class VideoPlayer { // 1.将构造器私有 private VideoPlayer() {} // 2.使用成员变量保存创建好的对象 private static VideoPlayer instance; // 3.提供公共的访问方式 public static VideoPlayer getInstance() { // 在使用时创建单例对象 if (instance == null) { instance = new VideoPlayer(); } return instance; } }
-
5、动态代理
5.1、代理模式介绍
- 概念
- 在程序的运行过程中创建出代理对象
5.2、动态代理的好处
- 可以对功能进行增强
- 可以对功能进行拦截
5.3、动态代理的使用场景
- 集成支付宝
- 支付后发短信,发邮件
- 使用动态代理
5.4、动态代理API使用
- Proxy类
- static Object new ProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- 方法的作用
- 创建代理对象,会实现传入的接口
- 返回值Object
- 代理对象
- 参数
- ClassLoader loader
- 类加载器(不是重点);固定格式---->当前类名.class.getClassLoader()
- Class[] interfaces:
- 接口数组
- InvocationHandler h
- 执行处理器接口,放入匿名内部类
- ClassLoader loader
5.5、使用动态代理拦截和增强ArrayList的功能
- 代理模式三要素
- 1.真实对象
- ArrayList
- 2.代理对象
- 使用动态代理API生成
- 3.抽象对象
- List接口
- 1.真实对象