xml的解析
xml:可擴展標記語言
標籤就是自定義
xml 的作用
1.配置文件
- 存數據(數據庫)
- 3.前端後傳遞數據(json)
xml的組成部分
1聲明:<?xml version='1.0' encoding='UTF-8'?>
<?xml開始於結束的?>
version='1.0' xml的版本(最新的是1.1)
encoding='UTF-8' ==> 編碼格式
2.元素==>html中的標籤 <name>文本</name>
3.屬性 <name id="1">文本</name> ==>比如id屬性
4. <![CDATA ]==>表示忽略特殊符號
5.註釋 ==>html中的註釋是一樣
xml中的特殊符號
驗證解析器
驗證解析器: 也就是瀏覽器會自動去識別xml的一些語法錯誤
xml 特點
1.不會編譯
2.只能存在一個根標籤
3.元素都是成對 ==>也有單個
4.區別大小寫
5.後綴名.xml
xml 解析
解析方式:
dom解析 , dom4j 解析(一般用於後臺)
注:以上兩種解析會把整個xml 加載到內存裏形成dom節點樹,然後再進行解析,但是xml內容過多會造成內存溢出
sax 解析方式:用於移動端是加載一行解析一行
問題:移動端 的內存比較小 ,解析比較麻煩
xpath解析方式:它既是依賴於dom4j進行操作也是dom解析的一種
dom解析
解析內容:xml文件
加載:加載成一個dom樹
對xmld 操作都是基於這個dom 對象
解析的步驟:
1.獲取dom對象的步驟 :
DocumentBuilderFactory==>調用 newInstance(); =>調用newDocumentBuilder()==>獲取到解析器 ==>調用其parse()方法 ==>轉換成一個dom 對象
//把文件換成dam對象
public Document getDom() {
try {
//解析器工廠得到解析器對象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//通過解析器工廠得到解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//通過解析器把文件轉換爲dom對象
Document document = db.parse(new File("web/收藏信息.xml"));
return document;
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return NULL;
}
顯示XML的數據:
document.getElementsByTagName(“Brand”)==>返回得到是 ==>NodeList ==>
遍歷 ==>得到每一一個Node ==>轉化成屬性節點 ==>根據鍵來獲取值 getAttribute(“name”); ==>獲取這個節點下的子節點 etChildNodes();
==>判斷是否是元素節點 Element.ELEMENT_NODE
//展示所有數據
public void show() {
Document document=getDom();//先獲取document對象
//獲取全部指定的節點
NodeList brand = document.getElementsByTagName("Brand");
for (int i = 0; i < brand.getLength(); i++) {
//獲取到每一節點對象
Node item = brand.item(i);
//把節點對象轉換爲元素屬性
Element element = (Element) item;
//通過屬性名獲取屬性值
String branName = element.getAttribute("name");
System.out.println(branName);
//獲取其子節點
NodeList childNodes = element.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node nodeType = childNodes.item(j);
//判斷是否是屬性節點
//注意空節點
if (nodeType.getNodeType() == Element.ELEMENT_NODE) {
//轉換爲屬性節點
Element elementNode = (Element) nodeType;
//獲取指定節點屬性的值
System.out.println(elementNode.getAttribute("name"));
}
}
}
}
把dom對象保存到xml
把dom對象保存到xml =>先創建一個解析器格式化工廠 TransformerFactory =>調用newTransformer()==> 獲取到這個類Transformer
==》transform(ds, sr); 把dom 對象寫入到文件裏 ==>
DOMSource ds = new DOMSource(document);
new StreamResult(new OutputStreamWriter(new FileOutputStream(path),“utf-8”));
//保存文件到xml
public void save(String path) {
Document document=getDom();//先獲取document對象
try {
//創建解析器格式化工廠
TransformerFactory tff = TransformerFactory.newInstance();
//獲取到格式化的類
Transformer transformer = tff.newTransformer();
//把dom對象寫入到文件
//Source接口
//result接口
DOMSource ds = new DOMSource(document);//獲取到dam對象
StreamResult rs = new StreamResult(new OutputStreamWriter(new FileOutputStream(path), "utf-8"));//獲取到寫入的位置
transformer.transform(ds, rs);//寫入到文件
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
增加一個節點 :
1.創建節點document.createElement(“Brand”);
2.設置其屬性 setAttribute(“name”, “opop”);
3.依次添加父子關係
//添加節點
public void addNode() {
Document document=getDom();//先獲取document對象
Element brand1 = document.createElement("Brand");
brand1.setAttribute("name", "opop");
//創建子節點
Element type = document.createElement("Type");
type.setAttribute("name", "R19");
//從上往下添加節點
document.getElementsByTagName("PhoneInfo").item(0).appendChild(brand1);
brand1.appendChild(type);
// document.appendChild(type);//Exception in thread "main" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: 嘗試在不允許的位置插入節點。
}
修改節點:
1。獲取節點 document.getElementsByTagName(“Brand” =》返回的是NodeList =>進行遍歷 =>得到Node------> 轉換爲屬性==》設置其值document.getElementsByTagName(“Brand”)
public void update() {//修改
Document document=getDom();//先獲取document對象
//獲取要修改的節點NodeList
NodeList nodelist = document.getElementsByTagName("Brand");
//遍歷集合
for (int i = 0; i < nodelist.getLength(); i++) {
//獲取到每個節點對象
Node node = nodelist.item(i);
//轉換爲屬性節點
Element element = (Element) node;
//設置屬性和值
element.setAttribute("id", (i + 1) + "");
}
}
刪除節點的步驟
1.通過 document.getElementsByTagName(“Brand”) 獲取到所有的節點 =NodeList =>遍歷 —>Node==>轉換爲屬性節點 ==》
getParentNode().removeChild(elementbrand) 一定要根據父節點來刪除子節點
//刪除
public void delete() {
Document document=getDom();//先獲取document對象
//獲取到要修改的節點
NodeList TagName = document.getElementsByTagName("Brand");
for (int i = 0; i < TagName.getLength(); i++) {
Node item = TagName.item(i);
//屬性節點
Element element = (Element) item;
//獲取這個節點的屬性的值
String name = element.getAttribute("name");
if ("opop".equals(name)) {//判斷值是否是要刪除的
//刪除節點
//根據父節點來刪除子節點
element.getParentNode().removeChild(element);
}
}
}
dom4j 解析
是對dom解析的一個封裝 ==>使得代碼量變量 注意點:需要導入第三方的dom4j .jar
-
把xml轉換成一個dom對象(dom4j jar 提供的)
1.實例化 SAXReader
2 . read(“傳遞是一個文件對象”)
-
把xml中的數據展示: 1.獲取其跟節點(getRootElement()) ==> 獲取到根節點下所有的元素 elementIterator() ==> 遍歷 迭代
-
增加一個節點:
- 獲取其跟節點(getRootElement())
- addElement(“Brand”);
- 設置其屬性addAttribute(“name”, “oppo”); =>不需要添加父子關係
- 修改
- 獲取其跟節點(getRootElement())
- 獲取到根節點下所有的元素 elementIterator() ==》遍歷 迭代
- 進行追加
- 刪除:根據父節點來刪除子節點
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
//反射:在new對象的時候把磁盤的.Class文件加載到內存(.class後綴文件是javac編譯來的),其實只有一個程序只有一個Class類,new多個對象,只是填充裏面的對應的數組長度
// 一個類裏面new 了兩個不一樣的對象,其中一個類調用點Class,會返回一個Class類 的對象,通過這個Class對象就可以訪問new 生成兩個類的內部的所有東西
public class Dom4j {
/*
* 把xml文件轉換爲一個dom樹,也就是dom對象
* */
static Document document;
public static void main(String[] args) {
Dom4j text = new Dom4j();
text.show();
text.add();
text.save("web/測試.xml");
}
public static void getDocument() {//獲取document對象
//作用類似解析器工廠
try {
SAXReader sr = new SAXReader();
document = sr.read(new File("web/收藏信息.xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
public void update() {
// 獲取根節點
Element rootElement = document.getRootElement();
//遍歷
int i = 0;//添加內容
for (Iterator<Element> iterator = rootElement.elementIterator(); iterator.hasNext(); ) {
i++;
Element next = iterator.next();
next.addAttribute("id", i + "");
}
}
//刪除
public void delete() {
Element rootElement = document.getRootElement();
for (Iterator<Element> iterator = rootElement.elementIterator(); iterator.hasNext(); ) {
Element next = iterator.next();
if (next.attributeValue("name").equals("華爲")) {
next.getParent().remove(next);
}
}
}
public void add() {
//添加節點,從根節點往下添加
//獲取根節點
Element rootElement = document.getRootElement();//獲取根節點
Element element = rootElement.addElement("Brand");//給根節點添加節點,返回的是添加的子節點
element.addAttribute("name", "小米");//給這個節點添加屬性
Element childNode = element.addElement("Type");//給這個節點添加兒子節點
childNode.addAttribute("name", "小米3");//給這個兒子節點添加屬性
}
public void save(String path) {
//實例化寫入的對象
try {
FileWriter fw = new FileWriter(path);//要寫入的文件
OutputFormat of = OutputFormat.createPrettyPrint();//創建一個標準的輸入格式,需要設置其寫入的編碼格式
of.setEncoding("UTF-8");//設置寫入和編碼格式
//寫入的主要對象
XMLWriter writer = new XMLWriter(fw, of);
//寫入的方法
writer.write(document);
//關閉流
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//顯示全部
public void show() {
//獲取根節點的方法
getDocument();//
Element rootElement = document.getRootElement();
for (Iterator<Element> iterator = rootElement.elementIterator(); iterator.hasNext(); ) {
Element predEle = iterator.next();
String predname = predEle.attributeValue("name");
System.out.println("---" + predname + "---");
Iterator iterator1 = predEle.elementIterator();
for (Iterator<Element> childIter = predEle.elementIterator(); childIter.hasNext(); ) {
Element child = childIter.next();
String childname = child.attributeValue("name");
System.out.println(childname);
}
}
}
}
http協議
概念:Hyper Text Transfer Protocol 超文本傳輸協議
* 傳輸協議:定義了,客戶端和服務器端通信時,發送數據的格式
* 特點:
1. 基於TCP/IP的高級協議
2. 默認端口號:80
3. 基於請求/響應模型的:一次請求對應一次響應
4. 無狀態的:每次請求之間相互獨立,不能交互數據
* 歷史版本:
* 1.0:每一次請求響應都會建立新的連接
* 1.1:複用連接
*http協議是有七種請求方式的:
*post, get, head, delete, options, trace, put
http協議是有七種請求方式的:
post, get, head, delete, options, trace, put
-
請求消息數據格式
-
請求行
請求方式 請求url 請求協議/版本
GET /login.html HTTP/1.1- 請求方式:
- HTTP協議有7中請求方式,常用的有2種
- GET:
- 請求參數在請求行中,在url後。
- 請求的url長度有限制的
- 不太安全
- POST:
- 請求參數在請求體中
- 請求的url長度沒有限制的
- 相對安全
- GET:
- HTTP協議有7中請求方式,常用的有2種
- 請求方式:
-
請求頭:客戶端瀏覽器告訴服務器一些信息
請求頭名稱: 請求頭值- 常見的請求頭:
-
User-Agent:瀏覽器告訴服務器,我訪問你使用的瀏覽器版本信息
- 可以在服務器端獲取該頭的信息,解決瀏覽器的兼容性問題
-
Referer:http://localhost:8080/login.html
- 告訴服務器,我(當前請求)從哪裏來?
- 作用:
- 防盜鏈:
- 統計工作:
- 作用:
- 告訴服務器,我(當前請求)從哪裏來?
-
- 常見的請求頭:
-
請求空行
空行,就是用於分割POST請求的請求頭,和請求體的。 -
請求體(正文):
- 封裝POST請求消息的請求參數的
-
字符串格式:
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1username=zhangsan
-
http 協議組成:
請求協議 ==>也就是瀏覽器給服務器發送請求所遵循的規則
與響應協議 ==>也就是服務器給客戶端響應所遵循的規則
http的組成: 分爲三個部分 1.請求行 2.請求體 3.請求頭
3.請求頭:1.都是一鍵值對來進行表示 ,這個鍵都是預定義:也及時瀏覽器給其響應的含義
響應 :分爲三個部分 1.響應頭 2.響應行 3.響應體
注 1. 響應頭
2.響應的狀態碼 1. 404 頁面找不到 302 重定向 500 服務器發生了異常(代碼出錯了) 200 請求成功 304(表示緩存)
https 協議 :
稱爲一次性協議(不安全) https=http+ssl證書(保護數據的安全性)
socket = >就是長連接 ==>只要連接成功,是不會斷開 ==》 socket中的心跳包來檢測是否連接成功 ,多用於即時通訊 xmpp+udp+tcp 結合使用
udp ==> 屬於長連接,面向無連接 ,效率高,安全性低
tcp==> 屬於長連接,面向連接 效率低,安全性高
反射:
反射:框架的靈魂 ==>所有的框架的技術都依賴於反射
框架:是一個半成品 ==> 使得開發更加簡單
反射中的熱修復:動態來修復bug 騰訊的bugly ==>反射
java代碼運行三個階段 1.源代碼階段 2.class階段 3.運行節點
反射:將類的各個部分組成一個新類 Class
練習
package com.student.xmlmanager.test;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Scanner;
public class Demo {
static Document document;
static boolean flag = false;
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
getdocument();//獲取document對象
do {
System.out.println("添加用戶 (a) 刪除用戶(b) 查詢成績(c)");
System.out.println("請輸入操作類型:");
char inpu = input.next().charAt(0);
switch (inpu) {
case 'a':
flag = true;
add();
break;
case 'b':
flag = true;
delete();
break;
case 'c':
flag = true;
select();
break;
case '0':
flag = false;
break;
}
} while (flag);
}
public static void add() {//添加用戶
System.out.println("請輸入學生姓名:");
String name = input.next();
System.out.println("請輸入學生準考號:");
String number = input.next();
System.out.println("請輸入身份證號");
String idcard = input.next();
System.out.println("請輸入學生所在地:");
String address = input.next();
System.out.println("請輸入學生的成績");
String grade = input.next();
Element rootElement = document.getRootElement();//先獲取根節點
Element student = rootElement.addElement("student");//添加子節點節點
student.addAttribute("idcard", idcard);//添加屬性
student.addAttribute("examid", number);
Element name1 = student.addElement("name");
name1.addText(name);//添加文本
Element location = student.addElement("location");
location.addText(address);
Element grade1 = student.addElement("grade");
grade1.addText(grade);
save();//保存到xml中
}
public static void delete() {//刪除
System.out.println("請輸入要刪除學生的姓名");
String name = input.next();
Element rootElement = document.getRootElement();//獲取根節點
for (Iterator<Element> iterator = rootElement.elementIterator(); iterator.hasNext(); ) {//遍歷根節點下的全部子節點
Element next = iterator.next();//其中一條
for (Iterator<Element> childNodeIt = next.elementIterator(); childNodeIt.hasNext(); ) {
Element child = childNodeIt.next();
if (name.equals(child.getText())) {//刪除要回到父節點刪除子節點,只有父親刪除兒子
child.getParent().getParent().remove(next);
System.out.println("刪除成功");
save();//修改完後重新保存
}
}
}
}
public static void select() {//查詢
System.out.println("請輸入要查詢的學生準考號");
String examid = input.next();
System.out.println("你查詢的學生信息爲:");
Element rootElement = document.getRootElement();
for (Iterator<Element> iterator = rootElement.elementIterator(); iterator.hasNext(); ) {
Element next = iterator.next();
if (examid.equals(next.attributeValue("examid"))) {
System.out.print("身份證:" + next.attributeValue("idcard") + ": 准考證號:" + next.attributeValue("examid") + ":");
for (Iterator<Element> childNodeIt = next.elementIterator(); childNodeIt.hasNext(); ) {
Element next1 = childNodeIt.next();
System.out.print(next1.getName() + ":" + next1.getText() + " :");
}
System.out.println("");
}
}
}
public static void getdocument() {
try {
SAXReader saxReader = new SAXReader();
document = saxReader.read(new File("web/exam.xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
// Writer writer, OutputFormat format
public static void save() {
try {
FileWriter fileWriter = new FileWriter("web/exam.xml");
OutputFormat prettyPrint = OutputFormat.createPrettyPrint();
prettyPrint.setEncoding("UTF-8");
XMLWriter xmlWriter = new XMLWriter(fileWriter, prettyPrint);
xmlWriter.write(document);
xmlWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
exam.xml
<?xml version="1.0" encoding="UTF-8"?>
<exam>
<student idcard="111" examid="222">
<name>張三</name>
<location>瀋陽</location>
<grade>89</grade>
</student>
<student idcard="123456789" examid="123456">
<name>小李</name>
<location>上阿海</location>
<grade>99</grade>
</student>
</exam>