XML
什么是XML
XML是一个可扩展标记语言。XML和操作系统编程语言的开发平台无关,可以实现不同系统之间的数据交换。
- XML的规范
XML文档内容是由一系列标签元素组成的。
<元素名 属性名=“属性值”>元素内容</元素名>
属性值用引号包裹
一个元素可以有多个属性
属性值不可以直接包含< &
不建议使用的字符" ’ >
使用IDEA新建一个XML文件,先尝试编写一个XML文件:
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<!--图书信息-->
<book id="b001">
<title>图书1</title>
<author>张三</author>
</book>
<book id="b002">
<title>图书2</title>
<author>李四</author>
</book>
<!--可以代表空元素-->
<book></book>
</books>
同时也可以在IDEA中查看编写XML文档的结构
也可以在浏览器中预览编写好的xml文件。
如何编写格式良好的XML
- XML中的转义符列表
具体参考XML的转义符列表
当元素中出现了很多的特殊字符时,可以使用CDATA节,CDATA是不应该由XML解析器解析的文本数据
<![CDATA[输出第一本<book></book>图书信息]]>
XML的编写注意事项:
所有的XML元素都必须有结束标签
XML标签对大小写敏感
XML必须是正确的嵌套
同级标签以缩进对齐
元素名称可以包含字母 数字 或者是其他的字符
元素名称不可以以数字或者是标点符号开始
元素名称不可以包含空格
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<!--图书信息-->
<book id="b001" width="<20">
输出第一本<book></book>图书信息
<title>图书1</title>
<author>张三</author>
</book>
<book id="b002">
<![CDATA[输出第一本<book></book>图书信息]]>
<title>图书2</title>
<author>李四</author>
</book>
<!--可以代表空元素-->
<book></book>
</books>
<?xml version="1.0" encoding="UTF-8" ?>
<clothSizes>
<!--衣服尺码和身高对比信息-->
<size range="height<165">S</size>
<size range="165<height<170">M</size>
<size range="170<height<175">L</size>
<size range="175<height<180">XL</size>
<size range="180<height<185">XXL</size>
</clothSizes>
<?xml version="1.0" encoding="UTF-8" ?>
<studentScores>
<student>
<name>王显明</name>
<expectedScore>78</expectedScore>
<score>88</score>
</student>
<student name="宋佳" expectedScor="80" score="90"/>
</studentScores>
在一个XML文档或者是多个XML文档中可能会有命名冲突的问题,这是十分常见的,那么怎么解决这种问题呢?
- XML命名空间的作用
可以解决在复杂 大型的XML文件中,出现名称相同 但是含义不同的元素,还可以在一个文档中定义多个命名空间
<cameras xmlns:canon="http://www.canon" xmlns:nikon="http://www.nikon.com"></cameras>
默认的命名空间
没有指定前缀的命名空间就会作为页面中的元素的默认命名空间
除非在标签中使用其他命名空间的前缀,否则解析器都会认为元素是在默认命名空间下存在
一个文档中只可以有一个默认的命名空间
DOM解析XML技术
- DOM
基于XML文档树结构的解析
适用于多次访问的XML文档
特点:比较消耗资源
- DOM4J
非常优秀的java xml API
性能优异 功能强大
开放源代码
- SAX
基于事件的解析
适用于大数据量的XML文档
特点:占用的资源少,内存消耗小
DOM是文档对象模型,DOM把XML文档映射成一个倒挂的树
-
常用的接口的介绍
DOM解析包:org.w3c.dom
-
DOM解析XML文件的步骤
创建解析器工厂对象
解析器工厂对象创建解析器对象
解析器对象指定XML文件创建Document对象
以Document对象为起点操作DOM树
- 保存XML文件
获得TransformerFactory对象
创建Transformer对象 设置输出属性
创建DOMSource对选哪个 包含XML信息
创建StreamResult对象 包含保存文件的信息
将XML保存在指定文件中
新建一个XML文件是收藏信息.xml
<?xml version="1.0" encoding="UTF-8" ?>
<PhoneInfo>
<Brand name="华为">
<Type name="Mate30 Pro"/>
<Type name="P30 Pro"/>
<Type name="nova 6"/>
</Brand>
<Brand name="苹果">
<Type name="iPhone11 pro"/>
</Brand>
</PhoneInfo>
编写java代码解析XML文档
package XML;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
//对XML文件的全部解析工作(查看 增加 修改 删除 保存)
public class ParseXMLDemo {
//全局变量:Document对象
Document document = null;
//解析XML文件获取相应的Document对象
public void getDocument() {
//解析器工厂(DocumentBuilderFactory)
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
//解析器(DocumentBuilder)
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse("收藏信息.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
//获取手机品牌和型号
public void showInfo() {
//获取手机的品牌
NodeList brands = document.getElementsByTagName("Brand");
//循环获取每一个手机品牌节点
for (int i = 0; i < brands.getLength(); i++) {
Node node = brands.item(i);
//把品牌节点转换为品牌元素
Element eleBrand = (Element) node;
//获取每一个品牌元素的name属性
System.out.println(eleBrand.getAttribute("name"));
//获得每个品牌节点下面的子节点(型号)
NodeList types = eleBrand.getChildNodes();
for (int j = 0; j < types.getLength(); j++) {
//拿出每一个型号节点
Node typeNode = types.item(j);
//判断型号节点是否为元素,如果是ELEMENT_NODE,再转换为元素
if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
//型号节点转换为型号元素
Element eleType = (Element) typeNode;
//获取型号元素的name属性
System.out.println("\t" + eleType.getAttribute("name"));
}
}
}
}
//添加新的节点
public void add() {
//创建新的品牌节点
Element elementBrand = document.createElement("Brand");
//为品牌节点创建name属性
elementBrand.setAttribute("name", "三星");
//创建新的型号节点
Element elementType = document.createElement("Type");
//为型号节点创建name属性
elementType.setAttribute("name", "Galaxy Fold");
//把型号节点作为品牌节点的子节点添加进去
elementBrand.appendChild(elementType);
//把三星新的品牌节点(带有子节点型号的)加到元素PhoneInfo中去
document.getElementsByTagName("phoneInfo").item(0).appendChild(elementBrand);
//保存XML
this.saveXML("new.xml");
}
//保存XML文件-->path:目的地
public void saveXML(String path) {
//转换器工厂
TransformerFactory factory = TransformerFactory.newInstance();
//转换器
try {
Transformer transformer = factory.newTransformer();
//设置输出格式(编码 缩进)
//transformer.setOutputProperty(OutputKeys.ENCODING,"gb2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
//源
DOMSource source = new DOMSource(document);
//目的
StreamResult result = new StreamResult(new File(path));
//完成XML文件保存
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
//实现XML节点的修改,Brand标签添加一个id属性
public void update() {
//获取所有的Brand元素
NodeList brands = document.getElementsByTagName("Brand");
for (int i = 0; i < brands.getLength(); i++) {
Node brand = brands.item(i);
Element eleBrand = (Element) brand;
//为每一个Brand元素设置id属性
eleBrand.setAttribute("id", i + "");
}
//保存XML
this.saveXML("new.xml");
}
//实现XML节点的删除 删除所有Brand为华为的节点
public void delete() {
//获取所有的Brand节点
NodeList brands = document.getElementsByTagName("Brand");
//遍历所有的Brand节点 找出华为
for (int i = 0; i < brands.getLength(); i++) {
Node brand = brands.item(i);
Element eleBrand = (Element) brand;
if (eleBrand.getAttribute("name").equals("华为")) {
eleBrand.getParentNode().removeChild(eleBrand);
}
}
//保存XML
this.saveXML("new.xml");
}
public static void main(String[] args) {
ParseXMLDemo parseXMLDemo = new ParseXMLDemo();
parseXMLDemo.getDocument();
// parseXMLDemo.add();
// parseXMLDemo.update();
parseXMLDemo.delete();
parseXMLDemo.showInfo();
}
}
JSON
JSON是一种轻量级的文本数据交换格式,具有自我描述性,比XML传输速度快
JSON最初用来表示javascript中的对象,但目前已经独立于javascript,成为最常用的数据格式之一。
JSON的语法格式
- 两种数据结构:对象和数组
大括号内为对象
中括号中是数组
- 对象中的数据由名称/值对构成
值得类型可以是字符串 数字 布尔值 null 数组 对象
数据之间由逗号分割开来
- 数据中的数据类型同名称/值对中值的类型
{
"name":"jason",
"age":20,
"skill":["java","python"]
}
使用fastjson解析JSON
package Kind;
import java.util.List;
public class Student {
private String name;
private int age;
private List<String> skills;
public Student() {
}
public Student(String name, int age, List<String> skills) {
super();
this.name = name;
this.age = age;
this.skills = skills;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", skills=" + skills +
'}';
}
public List<String> getSkills() {
return skills;
}
public void setSkills(List<String> skills) {
this.skills = skills;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package Test;
import Kind.Student;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
//完成学员对象和JSON字符串的互相转换
public class FastJSONDemo {
public static void main(String[] args) {
//对象转换为JSON字符串
List<String> skills = new ArrayList<>();
skills.add("java");
skills.add("python");
skills.add("linux");
Student student = new Student("Jason", 20, skills);
String stuJSON = JSON.toJSON(student).toString();
System.out.println(stuJSON);
//JSON字符串转换为对象
String json = "{\"skills\":[\"java\",\"python\",\"linux\"],\"name\":\"Jason\",\"age\":20}\n";
Student stu = JSON.parseObject(json, Student.class);
System.out.println("转换为学生对象:" + stu.getName() + "-" + stu.getAge() + "-" + stu.getSkills());
}
}
DOM4J解析XML文件
DOM4J有一些接口比较常用:
Document接口:定义XML文档
Element接口,定义XML元素
Text接口,定义XML文本节点
Attribute接口:定义了XML属性
DOM4J解析收藏信息.xml文件
package XML;
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;
//借助DOM4J的方式来解析收藏信息.xml
public class DOM4JXML {
//全局的Document
Document document = null;
//获取Document对象,为全局的Document赋值
public void getDocument() {
//通过解析器解析XML文件,获取Document
SAXReader saxReader = new SAXReader();
try {
document = saxReader.read(new File("E:\\file\\code\\java\\javacode\\src\\XML\\收藏信息"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
public void showPhoneInfo() {
//获取根节点
Element root = document.getRootElement();
//获取根节点下面的子节点,进行遍历
for (Iterator itBrand = root.elementIterator(); itBrand.hasNext(); ) {
Element brand = (Element) itBrand.next();//遍历迭代器中的每一个Brand节点
//显示品牌:brand的name属性
System.out.println("手机品牌:" + brand.attributeValue("name"));
//获取品牌下的手机型号
for (Iterator itType = root.elementIterator(); itType.hasNext(); ) {
Element type = (Element) itType.next();//遍历迭代器中的每一个Type节点
System.out.println("\t型号:" + type.attributeValue("name"));
}
}
}
//添加新的手机收藏信息(品牌和型号)
public void add() {
//获取XML的根节点
Element root = document.getRootElement();
//为根节点添加一个Brand元素,name赋值为三星
Element brand = root.addElement("Brand");
brand.addAttribute("name", "三星");
//为brand元素添加Type元素 Type元素name属性赋值为Glaxy Fold
Element type = brand.addElement("Type");
type.addAttribute("name", "Glaxy Fold");
//保存XML
this.saveXML("new.xml");
}
public void saveXML(String path) {
//创建一个XMLWriter对象,相当于DOM解析中的转换器
try {
//输出保存时的格式
OutputFormat format = OutputFormat.createPrettyPrint();
//format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(new FileWriter(path), format);
writer.write(document);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//修改手机收藏信息,为Brand元素设置ID属性
public void update() {
//获取XML的根元素
Element root = document.getRootElement();
//获取根元素下面的所有Brand子元素 遍历
int id = 0;
for (Iterator itBrands = root.elementIterator(); itBrands.hasNext(); ) {
Element brand = (Element) itBrands.next();
//为Brand元素设置ID属性
id++;
brand.addAttribute("id", id + "");
}
//保存XML文件
this.saveXML("new.xml");
}
public void delete() {
//获取XML的根元素
Element root = document.getRootElement();
//获取所有的Brand子元素 遍历
for (Iterator itBrands = root.elementIterator(); itBrands.hasNext(); ) {
Element brand = (Element) itBrands.next();
//判断Brand的name属性是否是华为 如果是 则删除
if (brand.attributeValue("name").equals("华为")) {
//由父节点进行删除
brand.getParent().remove(brand);
}
}
//保存XML文档
this.saveXML("new.xml");
}
//显示手机收藏信息
public static void main(String[] args) {
DOM4JXML dom4JXML = new DOM4JXML();
dom4JXML.getDocument();
dom4JXML.add();
dom4JXML.update();
dom4JXML.delete();
dom4JXML.showPhoneInfo();
}
}