0. 配置文件介绍和分类
介绍 :
- 好处 :
- 可以让项目中使用的数据, 灵活的加载和更变, 实现解耦
分类 :
- Properties : 常用于一对一的存储
- 键值对
- username=root
- password=123456
- xml : 常用于一对多的存储
1. XML 介绍
XML的全称为(EXtensible Markup Language),是一种可扩展的标记语言。
- 标记语言:通过标签来描述数据的一门语言(标签有时我们也将其称之为元素)
- 可扩展:标签的名字是可以自己定义的
优势 :
- 作为软件的配置文件
- 用于进行存储数据和传输数据
- 传输的理解, 主要还是喜欢它里面的格式
2. XML 语法
语法规则 :
-
创建
- 就是创建一个XML类型的文件,要求文件的后缀必须使用xml,如hello_world.xml
-
文档声明
文档声明必须是第一行第一列
<?xml version="1.0" encoding="UTF-8" ?>- version:该属性是必须存在的
- encoding:该属性不是必须的
- 打开当前xml文件的时候应该是使用什么字符编码表(一般取值都是UTF-8)
- standalone: 该属性不是必须的,描述XML文件是否依赖其他的xml文件,取值为yes/no
-
标签规则
- 必须存在一个根标签,有且只能有一个
-
标签由一对尖括号和合法标识符组成
<student>
-
标签必须成对出现
<student> </student> 前边的是开始标签,后边的是结束标签
-
特殊的标签可以不成对, 但是必须有结束标记
<address/>
-
标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来
<student id="1"> </student>
-
标签需要正确的嵌套
这是正确的: <student id="1"> <name>张三</name> </student> 这是错误的: <student id="1"> <name>张三 </student> </name>
- 细节
案例 :
- 需求 : 编写一个城市对应区的 xml 文件
- 城市: city
- 区域 : area
北京市 :
东城区
西城区
朝阳区
海淀区
昌平区
3. XML 约束 (了解)
这东西以后都不会自己写
介绍 :
- 用来限定xml文件中可使用的标签以及属性
分类 :
- DTD 约束
- schema 约束
DTD 约束
编写DTD约束
-
步骤
-
创建一个文件,这个文件的后缀名为.dtd
-
看xml文件中使用了哪些元素
<!ELEMENT> 可以定义元素 -
判断元素是简单元素还是复杂元素
简单元素:没有子元素。
复杂元素:有子元素的元素;
-
-
代码实现
<!ELEMENT persons (person)> <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)>
-
引入DTD约束
-
引入本地dtd
<!DOCTYPE 根元素名称 SYSTEM 'DTD文件的路径'>
-
在xml文件内部引入
<!DOCTYPE 根元素名称 [ dtd文件内容 ]>
-
引入网络dtd
<!DOCTYPE 根元素的名称 PUBLIC "DTD文件名称" "DTD文档的URL">
-
引入本地DTD约束
// 这是persondtd.dtd文件中的内容,已经提前写好 <!ELEMENT persons (person)> <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> // 在person1.xml文件中引入persondtd.dtd约束 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE persons SYSTEM 'persondtd.dtd'> <persons> <person> <name>张三</name> <age>23</age> </person> </persons>
-
在xml文件内部引入
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE persons [ <!ELEMENT persons (person)> <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> ]> <persons> <person> <name>张三</name> <age>23</age> </person> </persons>
-
引入网络dtd
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE persons PUBLIC "dtd文件的名称" "dtd文档的URL"> <persons> <person> <name>张三</name> <age>23</age> </person> </persons>
-
Schema 约束
-
schema 和 dtd 的区别
- schema约束文件也是一个xml文件,符合xml的语法,这个文件的后缀名.xsd
- 一个xml中可以引用多个schema约束文件,多个schema使用名称空间区分(名称空间类似于java包名)
- dtd里面元素类型的取值比较单一常见的是PCDATA类型,但是在schema里面可以支持很多个数据类型
- schema 语法更加的复杂
-
编写schema约束
1. 创建一个文件,这个文件的后缀名为.xsd
2. 定义文档声明
3. schema文件的根标签为: <schema>
4. 在<schema>中定义属性:
xmlns=http://www.w3.org/2001/XMLSchema
5. 在<schema>中定义属性:
targetNamespace = 唯一的url地址,指定当前这个schema文件的名称空间
理解: 起个名, 顺带打广告
6. 在<schema>中定义属性:
elementFormDefault="qualified“,表示当前schema文件是一个质量良好的文件
7. 通过element定义元素
8. 判断当前元素是简单元素还是复杂元素
示例 :
引入 :
<stus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mhys.com"
xsi:schemaLocation="http://www.mhys.com stus.xsd"
>
<student>
<name>张三</name>
<age>23</age>
</student>
</stus>
4. XML解析
- 解析的两种方式
- SAX 解析
- DOM 解析
准备动作
- 导入 dom4j-1.6.1.jar 包
- 获取 Document 对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("day15-code\\src\\xml\\stus.xml"));
System.out.println(document);
方法介绍
示例代码
package com.ligong.start;
import com.ligong.domain.Student;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
ArrayList<Student> list = new ArrayList<>();
// 1. 获取根标签
Element rootElement = document.getRootElement();
// 2. 获取根标签下的所有子标签
List<Element> student = rootElement.elements("student");
// 3. 遍历集合
for (Element element : student) {
// 4. 获取标签属性
String id = element.attributeValue("id");
// 5. 获取name标签的值
String name = element.element("name").getText();
// 6. 获取age标签的值
String age = element.element("age").getText();
// 7. 封装为Student学生对象
Student stu = new Student(name, Integer.parseInt(age));
// 8. 添加到集合
list.add(stu);
}
list.forEach(s -> System.out.println(s));
}
}
5. Xpath检索
- Dom 的弊端
- 如果需要从XML文件中检索需要的某个信息(如name)怎么解决?
- Dom4j需要进行文件的全部解析,然后再寻找数据
- Xpath 技术更加适合做信息检索
- 如果需要从XML文件中检索需要的某个信息(如name)怎么解决?
介绍
- XPath在解析XML文档方面提供了独树一帜的路径思想,更加优雅,高效
- XPath使用路径表达式来定位XML文档中的元素节点或属性节点
准备动作 :
- 导入 jaxen-1.1-beta-6.jar 包
- 主要 : 这东西依赖于 Dom4J 用的时候都得有
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
绝对路径示例代码 :
package com.ligong.start;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
public class Test {
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
// 获取单个节点
Node node = document.selectSingleNode("/students");
System.out.println(node.getText());
// 获取多个节点
List<Element> list = document.selectNodes("/students/student/name");
for (Element element : list) {
System.out.println(element.getText());
}
}
}
相对路径示例代码 :
- 相对于谁 : 根节点 rootElement
package com.ligong.start;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
public class A {
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
// 相对路径: 相对于根节点
Element rootElement = document.getRootElement();
// 获取单个
Node node = rootElement.selectSingleNode("./student/name");
System.out.println(node.getText());
// 获取多个节点
List<Element> list = rootElement.selectNodes("./student/age");
for (Element element : list) {
System.out.println(element.getText());
}
}
}
全文检索示例代码 :
package com.ligong.start;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
public class A {
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
// 获取多个节点 - 全文检索
List<Element> list1 = document.selectNodes("//name");
for (Element element : list1) {
System.out.println(element.getText());
}
System.out.println("---------------------------");
// 获取多个节点 - 全文检索 / (父节点下面的子节点)
List<Element> list2 = document.selectNodes("//student/name");
for (Element element : list2) {
System.out.println(element.getText());
}
System.out.println("---------------------------");
// 获取多个节点 - 全文检索 / (父节点下面的子节点, 孙子节点, 重孙子...)
List<Element> list3 = document.selectNodes("//student//name");
for (Element element : list3) {
System.out.println(element.getText());
}
}
}
属性查找示例代码:
package com.ligong.start;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
public class A {
public static void main(String[] args) throws DocumentException, FileNotFoundException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("mC\\src\\xml\\stus.xml"));
// 全文检索 : 所有属性
List<Attribute> list1 = document.selectNodes("//@id");
for (Attribute attribute : list1) {
System.out.println(attribute.getText());
}
System.out.println("---------------------------");
// 全文检索 : 带有指定属性的子标签
List<Element> list2 = document.selectNodes("//student[@id]");
for (Element element : list2) {
System.out.println(element.getName());
}
System.out.println("---------------------------");
// 全文检索 : 带有指定属性的子标签 + 标签值
List<Element> list3 = document.selectNodes("//student[@id=2]");
for (Element element : list3) {
System.out.println(element.element("name").getText());
}
}
}
总结 :
- 准备两个 jar 包
dom4j-1.6.1.jar
jaxen-1.1-beta-6.jar
SAXReader reader = new SAXReader();
Document document = reader.read(new File("xxxx"));
- 主要玩的两个方法 :
document.selectSingleNode("路径");
document.selectNodes("路径");
- 路径的两种写法 :
绝对路径 : 逐级查找
相对路径 : 相对于根节点 rootElement (了解)
./student/name
注意: 必须使用根标签对象, 调用方法.
- 全文检索 :
//name : 文件里所有的都找出来, 不考虑子父标签
//student/name : 找指定父节点下面的子标签
//student//name : 找父节点下面所有后辈的子标签
- 带属性查找
//@id : 文件里所有的都找出来, 不考虑子父标签
- 注意: 这东西玩的是属性, Attribute
//student[@id] : 找带有id属性的student标签
- 注意: 找到的是标签, Element
//student[@id='2'] : 跟上面一样, 找的是标签, 就是带有具体属性值
6. 工厂设计模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M5xxaXYe-1643258138017)(img\18.png)]
public class ComputerFactory {
/**
定义一个方法,创建对象返回
*/
public static Computer createComputer(String info){
switch (info){
case "huawei":
Computer c = new Huawei();
c.setName("huawei pro 16");
c.setPrice(5999);
return c;
case "mac":
Computer c2 = new Mac();
c2.setName("MacBook pro");
c2.setPrice(11999);
return c2;
default:
return null;
}
}
}