今日疫情新聞發(fā)布會直播手機(jī)游戲性能優(yōu)化軟件
目錄
- 1 XML
- 1.1 XML 概述
- 1.2 XML 語法規(guī)則
- 1.3 XML 文檔約束(了解)
- 1.3.1 DTD 約束
- 1.3.2 schema 約束
- 2 XML 解析
- 2.1 XML 解析概述
- 2.2 Dom4J 解析 XML 文件
- 2.3 XML 解析案例
- 3 XML 檢索
- 4 設(shè)計模式
- 4.1 工廠模式
- 4.2 裝飾模式
1 XML
在有些業(yè)務(wù)場景下,存儲數(shù)據(jù)或者傳輸數(shù)據(jù)給別人的時候需要滿足一定的規(guī)范進(jìn)行組織
1.1 XML 概述
XML 的全稱為(EXtensible Markup Language),是一種 可擴(kuò)展 的 標(biāo)記語言,是一種數(shù)據(jù)表示格式,可以用于自定義數(shù)據(jù)格式,可以描述非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu),常用于傳輸和存儲數(shù)據(jù)。
例如:
<?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 的幾個特點和使用場景
- 一是純文本,默認(rèn)使用
UTF-8
編碼;二是可嵌套; - 如果把 XML 內(nèi)容存為文件,那么它就是一個 XML 文件。
- XML 內(nèi)容經(jīng)常被 當(dāng)成消息進(jìn)行網(wǎng)絡(luò)傳輸,或者 作為配置文件用于存儲系統(tǒng)的信息。
1.2 XML 語法規(guī)則
- XML 的創(chuàng)建
就是創(chuàng)建一個 XML 類型的文件,要求文件的后綴名必須使用 xml
,如:helloworld.xml
。
- XML 文件的文檔聲明
XML 文件的文檔聲明必須在第一行
<?xml version="1.0" encoding="UTF-8" ?>
version
: XML 默認(rèn)的版本號碼、該屬性是必須存在的
encoding
:本 XML 文件的編碼
- XML 的標(biāo)簽 ( 元素 ) 規(guī)則
- 標(biāo)簽由一對尖括號和合法標(biāo)識符組成:
<name></name>
,必須存在一個根標(biāo)簽,有且只能有一個 - 標(biāo)簽必須成對出現(xiàn),有開始,有結(jié)束 :
<name></name>
- 特殊的標(biāo)簽可以不成對,但是必須有結(jié)束標(biāo)記,如 :
<br/>
- 標(biāo)簽中可以定義屬性,屬性和標(biāo)簽名空格隔開 ,屬性值必須用引號引起來
<student id = “1”></name>
- 標(biāo)簽需要正確的嵌套
- XML 文件中可以定義注釋信息:
<!-- 注釋內(nèi)容 -->
- XML 文件中可以存在以下特殊字符
<
:<
小于>
:>
大于&
:&
和號'
:'
單引號"
:"
引號
- XML 文件可以存在 CDATA 區(qū) (IDEA中輸入CD再回車)
示例代碼
<?xml version="1.0" encoding="UTF-8" ?>
<student><msg>age > 18 && age <24<![CDATA[age>18 && age<24]]></msg>
</student>
1.3 XML 文檔約束(了解)
問題:由于 XML 文件可以自定義標(biāo)簽,導(dǎo)致 XML 文件可以隨意定義,程序在解析的時候可能出現(xiàn)問題。
文檔約束是用來限定 XML 文件中的標(biāo)簽以及屬性應(yīng)該怎么寫,以此強(qiáng)制約束程序員必須按照文檔約束的規(guī)定來編寫 XML 文件中
文檔約束可以分為:DTD和 schema 兩種
1.3.1 DTD 約束
需求:利用 DTD 文檔約束,約束一個 XML 文件的編寫。
分析:
- 編寫 DTD 約束文檔,后綴必須是
.dtd
- 在需要編寫的 XML 文件中導(dǎo)入該 DTD 約束文檔
- 按照約束的規(guī)定編寫 XML 文件的內(nèi)容
示例代碼
XML 的文檔約束 -DTD 的作用和問題?
- 可以約束 XML 文件的編寫。
- 不能約束具體的數(shù)據(jù)類型。
1.3.2 schema 約束
schema 可以約束具體的數(shù)據(jù)類型,約束能力上更強(qiáng)大,但由于其本身也是一個 XML 文件,也受到其他約束文件的要求,所以編寫地更嚴(yán)謹(jǐn)
需求:利用 schema 文檔約束,約束一個 XML 文件的編寫。
分析:
- 編寫 schema 約束文檔,后綴必須是
.xsd
- 在需要編寫的 XML 文件中導(dǎo)入該 schema 約束文檔
- 按照約束內(nèi)容編寫 XML 文件的標(biāo)簽。
示例代碼
2 XML 解析
2.1 XML 解析概述
XML 的數(shù)據(jù)的作用是什么,最終需要怎么處理?
- 存儲數(shù)據(jù)、做配置信息、進(jìn)行數(shù)據(jù)傳輸。
- 最終需要被程序進(jìn)行讀取,解析里面的信息。
主要有兩種解析方式: SAX 解析、DOM 解析
Dom 常見的解析工具
DOM 解析解析文檔對象模型
Document
對象:整個 xml 文檔
Node
對象
Element
對象:標(biāo)簽Attribute
對象:屬性Text
對象:文本內(nèi)容
2.2 Dom4J 解析 XML 文件
需求:使用 Dom4J 把一個 XML 文件的數(shù)據(jù)進(jìn)行解析
分析:
- 下載 Dom4j 框架,官網(wǎng)下載。
- 在項目中創(chuàng)建一個文件夾: lib
- 將 dom4j-2.1.1.jar 文件復(fù)制到 lib 文件夾
- 在 jar 文件上點右鍵,選擇 Add as Library -> 點擊 OK
- 在類中導(dǎo)包使用
Dom4j 解析 XML- 得到 Document 對象
SAXReader類
Document 類
Dom4j 解析 XML 的元素、屬性、文本
示例代碼
XML文件
<?xml version="1.0" encoding="UTF-8"?>
<contactList><contact id="1" vip="true">哈哈哈<name> 潘金蓮 </name><gender>女</gender><email>panpan@it.cn</email></contact><contact id="2" vip="false"><name>武松</name><gender>男</gender><email>wusong@it.cn</email></contact><contact id="3" vip="false"><name>武大狼</name><gender>男</gender><email>wuda@it.cn</email></contact><user></user>
</contactList>
解析XML文件
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;public class Dom4jDemo {@Testpublic void parseXML() throws Exception{// 1. 創(chuàng)建一個Dom4j解析器對象,代表了整個Dom4j框架SAXReader saxReader = new SAXReader();// 2. 把XML文件加載到內(nèi)存中稱為一個Document對象
// Document document = saxReader.read("xml\\src\\Contacts.xml");
// Document document = saxReader.read(new File("xml\\src\\Contacts.xml"));
// Document document = saxReader.read(new FileInputStream("xml\\src\\Contacts.xml"));// getResourceAsStream 中的/是直接去src下尋找文件InputStream is = Dom4jDemo.class.getResourceAsStream("/Contacts.xml");Document document = saxReader.read(is);// 3. 獲取根元素對象Element rootElement = document.getRootElement();System.out.println(rootElement.getName()); // contactList// 4. 獲取子元素// 4.1 獲取根元素下所有的子元素(一級)
// List<Element> elements = rootElement.elements();
// for (Element element : elements) {
// System.out.println(element.getName());
// }// 4.2 獲取某個子元素(若同名,默認(rèn)提取第一個子元素對象)Element contact = rootElement.element("contact");System.out.println(contact.getName()); // contact// 4.3 獲取當(dāng)前元素的文本System.out.println(contact.getText());// 去掉前后空格System.out.println(contact.getTextTrim()); // 哈哈哈// 4.4 獲取子元素文本System.out.println(contact.elementText("name"));// 去掉前后空格System.out.println(contact.elementTextTrim("name")); // 潘金蓮// 4.5 根據(jù)元素獲取屬性值Attribute id = contact.attribute("id");// 打印屬性名和屬性值System.out.println(id.getName()+":"+id.getValue());// 4.6 直接獲取屬性值System.out.println(contact.attributeValue("id")); // 1System.out.println(contact.attributeValue("vip")); // true}
}
2.3 XML 解析案例
需求 : 利用 Dom4J 的知識,將 Contact.xml 文件中的聯(lián)系人數(shù)據(jù)封裝成 List 集合,其中每個元素是實體類 Contact 。打印輸出 List 中的每個元素。
案例用到的 XML 文件見上文
創(chuàng)建 Contact 類
public class Contact {private String name;private int id;private boolean vip;private char gender;private String email;public Contact() {}public Contact(String name, int id, boolean vip, char gender, String email) {this.name = name;this.id = id;this.vip = vip;this.gender = gender;this.email = email;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public boolean isVip() {return vip;}public void setVip(boolean vip) {this.vip = vip;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "Contact{" +"name='" + name + '\'' +", id=" + id +", vip=" + vip +", gender=" + gender +", email='" + email + '\'' +'}';}
}
解析XML
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;import java.lang.invoke.StringConcatException;
import java.util.ArrayList;
import java.util.List;public class TestDemo {@Testpublic void parseToList() throws Exception {// 1. 創(chuàng)建saxReader對象SAXReader saxReader = new SAXReader();// 2. 加載XML文件成為Document對象Document document = saxReader.read(TestDemo.class.getResourceAsStream("/Contacts.xml"));// 3. 先獲取根元素Element rootElement = document.getRootElement();// 4. 獲取所有的contact子元素List<Element> contactEles = rootElement.elements("contact");// 5. 準(zhǔn)備一個ArrayList集合封裝聯(lián)系人信息ArrayList<Contact> contactsList = new ArrayList<>();// 6. 遍歷每一個contact子元素for (Element contactEle : contactEles) {// 7. 每一個contact子元素都是一個聯(lián)系人對象Contact contact = new Contact();// 8. 提取信息并給對象賦值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.把聯(lián)系人對象放入List集合contactsList.add(contact);}// 10. 遍歷集合for (Contact contact : contactsList) {System.out.println(contact);}}
}
輸出結(jié)果
總結(jié)
- Dom4J 解析 XML 文件的核心思想
- 得到文檔對象 Document ,從中獲取元素對象和內(nèi)容。
- Dom4J 的解析后的數(shù)據(jù)形式。
- 通常數(shù)據(jù)會封裝成 Java 的對象,如單個對象,或者集合對象形
式。
3 XML 檢索
如果需要從 XML 文件中檢索需要的某個信息(如 name )怎么解決?
- Dom4j 需要進(jìn)行文件的全部解析,然后再尋找數(shù)據(jù)。
- Xpath 技術(shù)更加適合做信息檢索。
XPath 在解析 XML 文檔方面提供了一獨樹一幟的路徑思想,更加優(yōu)雅,高效。XPath 使用路徑表達(dá)式來定位 XML 文檔中的元素節(jié)點或?qū)傩怨?jié)點。
使用 Xpath 檢索出 XML 文件
需求:使用 Dom4J 把一個 XML 文件的數(shù)據(jù)進(jìn)行解析
分析:
- 導(dǎo)入 jar 包 (dom4j 和 jaxen-1.1.2.jar) , Xpath 技術(shù)依賴 Dom4j 技術(shù)
- 通過 dom4j 的 SAXReader 獲取 Document 對象
- 利用 XPath 提供的 API, 結(jié)合 XPath 的語法完成選取 XML 文檔元素節(jié)點進(jìn)行解析操作。
Document 中與 Xpath 相關(guān)的 API
Xpath 的四大檢索方案
- 絕對路徑:采用絕對路徑獲取從根節(jié)點開始逐層的查找 /contactList/contact/name 節(jié)點列表并打印信息
- 相對路徑:先得到根節(jié)點 contactList,再采用相對路徑獲取下一級 contact 節(jié)點的 name 子節(jié)點并打印信息
- 全文檢索:直接全文搜索所有的 name 元素并打印
- 屬性查找:在全文中搜索屬性,或者帶屬性的元素
示例代碼
XML文件
<?xml version="1.0" encoding="UTF-8"?>
<contactList><contact id="1" vip="true"><name> 潘金蓮 </name><gender>女</gender><email>panpan@itcast.cn</email></contact><contact id="2" vip="false"><name>武松</name><gender>男</gender><email>wusong@itcast.cn</email></contact><contact id="3" vip="false"><name>武大狼</name><gender>男</gender><email>wuda@itcast.cn</email></contact><user><contact><info><name id="666">西門慶</name></info></contact></user>
</contactList>
檢索XML
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;import java.util.List;public class XPathDemo {// 1. 絕對路徑@Testpublic void parse01() throws Exception {// 創(chuàng)建解析器對象SAXReader saxReader = new SAXReader();// 將XML文件加載成Document對象Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));// 檢索全部名稱:name值List<Node> nodes = document.selectNodes("/contactList/contact/name");for (Node node : nodes) {Element nameEle = (Element) node;System.out.println(nameEle.getTextTrim());}}// 2. 相對路徑@Testpublic void parse02() throws Exception {// 創(chuàng)建解析器對象SAXReader saxReader = new SAXReader();// 將XML文件加載成Document對象Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));Element rootElement = document.getRootElement();// 檢索全部名稱:name值List<Node> nodes = rootElement.selectNodes("./contact/name");for (Node node : nodes) {Element nameEle = (Element) node;System.out.println(nameEle.getTextTrim());}}// 3. 全文搜素@Testpublic void parse03() throws Exception {// 創(chuàng)建解析器對象SAXReader saxReader = new SAXReader();// 將XML文件加載成Document對象Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));// 檢索數(shù)據(jù)
// List<Node> nodes = document.selectNodes("//name");// 會找"西門慶"
// List<Node> nodes = document.selectNodes("//contact/name");// 不會找"西門慶"List<Node> nodes = document.selectNodes("//contact//name");// 會找"西門慶"for (Node node : nodes) {Element nameEle = (Element) node;System.out.println(nameEle.getTextTrim());}}// 4. 屬性查找@Testpublic void parse04() throws Exception {// 創(chuàng)建解析器對象SAXReader saxReader = new SAXReader();// 將XML文件加載成Document對象Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));// 檢索數(shù)據(jù)// 在全文中檢索屬性對象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]");// 在全文中檢索屬性對象且屬性值為該值的元素對象Node node = document.selectSingleNode("//name[@id=666]");Element ele = (Element) node;System.out.println(ele.getTextTrim());}
}
Element
和繼承Node
4 設(shè)計模式
4.1 工廠模式
之前我們創(chuàng)建類對象時,都是使用 new 對象的形式創(chuàng)建,在很多業(yè)務(wù)場景下也提供了不直接 new 的方式 。
工廠模式( Factory Pattern )是 Java 中最常用的設(shè)計模式之一, 這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種獲取對象的方式。
工廠設(shè)計模式的作用:
- 工廠的方法可以封裝對象的創(chuàng)建細(xì)節(jié),比如:為該對象進(jìn)行加工和數(shù)據(jù)注入。
- 可以實現(xiàn)類與類之間的解耦操作(核心思想)
4.2 裝飾模式
裝飾設(shè)計模式:創(chuàng)建一個新類,包裝原始類,從而在新類中提升原來類的功能。
裝飾設(shè)計模式的作用:
- 裝飾模式指的是在不改變原類的基礎(chǔ)上 ,動態(tài)地擴(kuò)展一個類的功能