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>