Day14、XML-设计模式等
![image-20220526155309250]()
XML
XML 概述
XML 是可扩展标记语言(eXtensible Markup Language) 的缩写, 它是是一种数据表示格式, 可以描述非常复杂的数据结构, 常用于传输和存储数据。
<?xml version="1.0" encoding="UTF-8"?>
<data>
<sender> 张三</sender>
<receiver> 李四</receiver>
<src>
<addr>北京</addr>
<date>2022-11-11 11:11:11 </date>
</src>
<current>武汉</current>
<dest> 广州</dest>
</data>
XML 的几个特点和使用场景
-
一是纯文本, 默认使用UTF-8 编码; 二是可嵌套,
-
如果把XML 内容存为文件, 那么它就是一个XML 文件。
-
XML 的使用场景:XML 内容经常被当成消息进行网络传输, 或者作为配置文件用于存储系统的信息。
总结:
![image-20220526160018500]()
XML的创建
-
就是创建一个XML类型的文件,要求文件的后缀必须使用xml,如hello_world.xml
IDEA创建XML文件的操作步骤
![image-20220526160249989]()
XML的语法规则
-
XML文件的后缀名为:xml
-
文档声明必须是第一行
<?xml version="1.0" encoding="UTF-8" ?>
version:XML默认的版本号码、该属性是必须存在的
encoding:本XML文件的编码
XML的标签(元素)规则
-
标签由一对尖括号和合法标识符组成: , 必须存在一个根标签, 有且只能有一个。
-
标签必须成对出现, 有开始, 有结束:
-
特殊的标签可以不成对, 但是必须有结束标记, 如:
-
标签中可以定义属性, 属性和标签名空格隔开, 属性值必须用引号引起来<
-
标签需要正确的嵌套
-
![image-20220526161341763]()
XML 的其他组成
-
XML 文件中可以定义注释信息:
-
XML 文件中可以存在以下特殊字符
< < 小于
> > 大于
& & 和号
' ' 单引号
" " 双引号
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 注释:根标签有且仅能有一个--> <!--快捷键ctrl + shift + /-->
<student>
<name>女儿国王</name>
<sex>女</sex>
<hobby>唐玄奘,追玄奘</hobby>
<info>
<age>30</age>
<addr>女儿国</addr>
</info>
<sql>
select * from user where age < 18;
select * from user where age < 18 && age > 10
<![CDATA[
select * from user where age < 18
]]>
</sql>
总结:
![image-20220526191207078]()
什么是文档约束
-
文档约束: 是用来限定xml文件中的标签以及属性应该怎么写。
-
以此强制约束程序员必须按照文档约束的规定来编写xml文件。
文档约束的分类
步骤 :XML文档约束 -DTD的使用
![image-20220526191642156]()
总结:XML的文档约束-DTD的作用和问题?
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE 书架 SYSTEM "data.dtd">
<书架>
<书>
<书名>JAVAEE SSM</书名>
<作者>Newb</作者>
<售价>30</售价>
</书>
<书>
<书名>人鬼情未了</书名>
<作者>who</作者>
<售价>each</售价>
</书>
</书架>
文档约束-schema
-
schema 可以约束具体的数据类型, 约束能力上更强大。
-
schema 本身也是一个xml 文件, 本身也受到其他约束文件的要求, 所以编写的更加严谨
![image-20220526192744071]()
步骤:XML文档约束-schema的使用(了解)
![image-20220526192819936]()
总结:
XML的文档约束-schema的优点
-
可以约束XML文件的标签内容格式,以及具体的数据类型
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcsat.cn"
elementFormDefault="qualified">
<!--targetNamespace:申明约束文档的地址(命名空间)-->
<element name='书架'>
<!--写子元素-->
<complexType>
<sequence maxOccurs="unbounded">
<element name="书">
<!--写子元素-->
<complexType>
<sequence>
<element name="书名" type="string"/>
<element name="作者" type="string"/>
<element name="售价" type="double"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
XML解析技术
![image-20220526195232057]()
什么是XML解析
两种解析方式:
![image-20220526195336727]()
DOM常用的解析工具
![image-20220526195514817]()
DOM解析解析文档对象模型
![image-20220526195735005]()
总结:
![image-20220526195811655]()
步骤:使用DOM4j解析处XML文件
![image-20220526195852318]()
Dom4j 解析XML- 得到Document 对象
SAXReader 类
| 构造器 |
方法 |
| public SAXReader() |
创建Dom4J的解析器对象 |
| Document read(String url) |
加载XML 文件成为Document 对象 |
| Document 类 |
说明 |
| EIement getRootEIement() |
获得根元素对象 |
public class Dom4JHelloWorldDemo01 {
@Test
public void parseXMLData() throws Exception {
//1.创建一个dom4j的解析器对象,代表了整个dom4j框架
SAXReader saxReader = new SAXReader();
//2.把XML文件加载到内存中成为一个Document文档对象
/*
Document document = saxReader.read(new File("Day14-oop\\src\\Contacts.xml"));
需要通过模块名去定位
*/
//Document document = saxReader.read(new FileInputStream("Day14-oop\\src\\Contacts.xml"));
//注意:getResourceAsStream中的/是直接去src下寻找的文件
InputStream is = Dom4JHelloWorldDemo01.class.getResourceAsStream("/Contacts.xml");
Document document = saxReader.read(is);
Element root = document.getRootElement();
System.out.println(root.getName());
}
}
Dom4j解析XML的元素、属性、文本
| 方法名 |
说明 |
| List elements() |
得到当前元素下所有子元素 |
| List elements(String name) |
得到当前元素下指定名字的子元素返回集合 |
| EIement eIement(String name) |
得到当前元素下指定名字的子元素, 如果有很多名字相同的返回第一 |
| String getName() |
得到元素名字 |
| String attributeValue(String name) |
通过属性名直接得到属性值 |
| String elementText( 子元素名) |
得到指定名称的子元素的文本 |
| String getText() |
得到文本 |
public class Dom4JHelloWorldDemo01 {
@Test
public void parseXMLData() throws Exception {
//1.创建一个dom4j的解析器对象,代表了整个dom4j框架
SAXReader saxReader = new SAXReader();
//2.把XML文件加载到内存中成为一个Document文档对象
/*
Document document = saxReader.read(new File("Day14-oop\\src\\Contacts.xml"));
需要通过模块名去定位
*/
//Document document = saxReader.read(new FileInputStream("Day14-oop\\src\\Contacts.xml"));
//注意:getResourceAsStream中的/是直接去src下寻找的文件
InputStream is = Dom4JHelloWorldDemo01.class.getResourceAsStream("/Contacts.xml");
Document document = saxReader.read(is);
//3.获取根元素对象
Element root = document.getRootElement();
System.out.println(root.getName());
//4.拿根元素下的所有子元素(一级子元素)
List<Element> sonEles = root.elements("contact");
for (Element sonEle : sonEles) {
System.out.println(sonEle.getName());
}
//拿某个子元素
Element userEle = root.element("user");
System.out.println(userEle.getName());
//默认提取第一个子元素对象
Element contact = root.element("contact");
//获取子元素文本
System.out.println(contact.elementText("name"));
//去掉前后空格
System.out.println(contact.elementTextTrim("name"));
//根据元素获取属性值
Attribute idAtter = contact.attribute("id");
System.out.println(idAtter.getName() + "--->" + idAtter.getValue());
//直接提取属性值
System.out.println(contact.attributeValue("id"));
System.out.println(contact.attributeValue("vip"));
Attribute idAtter1 = contact.attribute("vip");
System.out.println(idAtter1.getName() + "--->" + idAtter1.getValue());
//获取当前元素下的子元素对象
Element email = contact.element("email");
System.out.println(email.getText());
}
}
总结:Dom4J的解析思想?
-
得到文档对象Document,从中获取元素对象和内容
案例:XML解析案例
![image-20220526205515852]()
![image-20220526205827421]()
public class Dom4jTest2 {
//解析xml中的数据成为一个list集合对象
@Test
public void parseToList() throws Exception{
//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集合封装联系人信息
ArrayList<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.elementTextTrim("email"));
//9.把联系人对象数据加入到list集合
contacts.add(contact);
}
//10.遍历List集合
for (Contact contact : contacts) {
System.out.println(contact);
}
}
}
/*
Contact{name='潘金莲', id=1, vip=true, gender=女, email='good@gmail.com'}
Contact{name='武松', id=2, vip=false, gender=男, email='wusong@gmail.com'}
Contact{name='武大郎', id=3, vip=false, gender=男, email='wudalang@gmail.com'}
*/
XML检索技术:Xpath
![image-20220526211957972]()
XPath 介绍
-
XPath 在解析XML 文档方面提供了一独树一帜的路径思想, 更加优雅, 高效
-
XPath 使用路径表达式来定位XML 文档中的元素节点或属性节点。
示例
步骤 :使用Xpath检索出XML文件
![image-20220526212853761]()
Xpath的四大检索方案
绝对路径-相对路径-全文检索-属性查找
public class XpathDemo {
//1.绝对路径:/ 根元素/ 子元素/ 孙元素
@Test
public void parse01() throws Exception{
//a.创建解析器对象
SAXReader saxReader = new SAXReader();
//b.把XML加载成Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/Contacts2.xml"));
//c.检索全部的名称
//List<Node> nameNodes("表达式") -> 获取符合表达式的元素集合
List<Node> nameNodes = document.selectNodes("/contactList/contact/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getTextTrim());
}
}
//2.相对路径 ./子元素/子元素(.代表了当前元素)
@Test
public void parse02() throws Exception{
//a.创建解析器对象
SAXReader saxReader = new SAXReader();
//b.把XML加载成Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/Contacts2.xml"));
Element root = document.getRootElement();
//c.检索全部的名称
List<Node> nameNodes = root.selectNodes("./contact/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getTextTrim());
}
}
//3.全文解锁
//元素 在全文找这个元素
//元素1/元素2 在全文找元素1下面的一级元素2
//元素1//元素2 在全文找元素1下面的全部元素2
@Test
public void parse03() throws Exception{
//a.创建解析器对象
SAXReader saxReader = new SAXReader();
//b.把XML加载成Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/Contacts2.xml"));
//c.检索数据
//List<Node> nameNodes = document.selectNodes("//name");
//List<Node> nameNodes = document.selectNodes("//contact/name");
List<Node> nameNodes = document.selectNodes("//contact//name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getTextTrim());
}
}
//4.属性查找
//@属性查找 在全文检索属性对象
//元素[@属性名称] 在全文检索包含该属性的元素对象
//元素[@属性名称=值] 在全文检索包含该属性的元素且属性值为该值的元素对象
@Test
public void parse04() throws Exception{
//a.创建解析器对象
SAXReader saxReader = new SAXReader();
//b.把XML加载成Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/Contacts2.xml"));
//c.检索数据
List<Node> nodes = document.selectNodes("//@id");
for (Node node : nodes) {
Attribute attr = (Attribute) node;
System.out.println(attr.getName() + "-->" + attr.getValue());
}
//查询name元素 包含id属性的
/*Node node = document.selectSingleNode("//name[@id]");
Element ele = (Element)node;
System.out.println(ele.getTextTrim());*/
Node node1 = document.selectSingleNode("//name[@id=888]");
Element ele1 = (Element)node1;
System.out.println(ele1.getTextTrim());
}
}
总结:Xpath作用,四大类
-
检索XML 文件中的信息
-
绝对路径:/ 根元素/ 子元素/ 孙元素
-
相对路径: · / 子元素/ 孙元素
-
-
属性查找: //@属性名、/ / 元素[@属性名] 、/ / 元素[@属性名=值]
设计模式:工厂模式
什么是工厂设计模式?
-
之前我们创建类对象时, 都是使用new 对象的形式创建, 在很多业务场景下也提供了不直接new 的方式。
-
工厂模式( Factory Pattern ) 是Java 中最常用的设计模式之一, 这种类型的设计模式属于创建型模式, 它提供了一种获取对象的方式。
工厂设计模式的作用:
-
工厂的方法可以封装对象的创建细节, 比如: 为该对象进行加工和数据注入。
-
可以实现类与类之间的解耦操作( 核心思想) 。
总结:工厂设计模式的作用
-
对象通过工厂的方法创建返回,工厂的方法可以为该对象进行加工和数据注入
-
可以实现类与类之间的解耦操作
设计模式:装饰模式
什么是装饰设计模式?
-
创建一个新类, 包装原始类, 从而在新类中提升原来类的功能。
装饰设计模式的作用:
-
作用: 装饰模式指的是在不改变原类的基础上, 动态地扩展一个类的功能。
lnputstream( 抽象父类)
FilelnputStream( 实现子类, 读写性能较差)
BufferedinputStream( 实现子类, 装饰类, 读写性能高)
-
定义父类。
-
定义原始类, 继承父类, 定义功能。
-
定义装饰类, 继承父类/ 包装原始类, 增强功能! !
后续
![image-20220527093339688]()