一,XML是什么?
XML:Extensible Markup Language 可扩展标记语言
XML可以将数据与HTML的格式分离.
比如要在HTML中显示动态的数据,那么每当数据改变时,都需要花费时间来编辑HTML中的各种标签元素什么的,
通过XML文件,数据能够存储在独立的XML文件中,这样可以保证,当修改底层数据时,不再需要对HTML文件做任何更改.
而外部的XML文件,也可以通过JS来读取,然后更新HTML中的数据内容.
不同的计算机系统,不同的应用程序,不同的客户端等,存储信息的格式很可能是不同的,而XML数据,是以纯文本的格式进行存储的,
所以可以通过XML数据来在不同的环境中共享数据(像不像JavaScript Object Notation).
所以说XML数据,提供了一种独立于软件和硬件的数据存储方式.
二,XML中的节点
Node对象,就是XML文件中的节点,XML文件中的节点有很多,常用的有三种,元素(标签),属性(标签中的属性),文本(开始结束标签中的文本内容)
需要注意的是:XML文件不像HTML文件那样会忽略空白字符,XML中是识别空格,制表符,换行符等空白字符的.
与src文件平级,建立一个test.xml文件,文件内容如下.
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1">
<name>张三</name>
<score>30</score>
<like>basketball</like>
<goodat>dance</goodat>
</student>
<student id="2">
<name>李四</name>
<score>40</score>
<like>lol</like>
<goodat>song</goodat>
</student>
</students>
三,DOM解析
DOM解析,会将XML文件中的所有内容,一次性加载进内存中解析.
先获取XML文件中的数据
//要解析xml中的数据,需要先获得内容,就相当于网络拉取的过程
//第一步创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//第二步创建一个DocumentBuilder的对象
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//第三步:(可以传入绝对路径也可以传入相对路径)
//通过parse方法加载test.xml文件到当前目录下(这样就将文件中的数据信息加载到document对象上了)
//得到document对象,注意是:org.w3c包下的
org.w3c.dom.Document document = documentBuilder.parse("test.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
获得所有的student节点
//下面是解析的步骤
//第一步,通过标签名获得标签(是所有student节点的集合)
NodeList studentList = document.getElementsByTagName("student");
//test.xml文件中,有两个student标签,这里获得的集合中输出的length也就是2
System.out.println("一共有: " + studentList.getLength());
获得student节点的属性
1,已知节点的属性(比如这里知道节点的属性为id)
for (int i = 0;i<studentList.getLength() ;i++ ) {
//获取集合中第i位置的元素
Element element = (Element)studentList.item(i);
//通过属性名获取该元素的属性值
String id = element.getAttribute("id");
}
2,不知道节点的属性有多少值都是什么
//获取属性名属性值,遍历每一个student节点
for (int i = 0; i < studentList.getLength(); i++) {
//通过 item(i)方法 获取一个student的节点信息(索引都是从零开始的)
//Node类的对象,就表示一个节点对象,含有该节点的信息
Node student = studentList.item(i);
//获得student这个节点的所有属性的集合
NamedNodeMap attrs = student.getAttributes();
for (int j = 0; j < attrs.getLength(); j++) {
Node attr = attrs.item(j);//获取属性
System.out.printf(attr.getNodeName());//获得属性名称
System.out.println(attr.getNodeValue());//获得属性值
}
}
获得student节点的子节点
student节点的子节点有:文本,name元素,文本,score,文本,like,文本,goodat,文本
所以student一共有9个子节点,下面获得节点name和value并打印出来
NodeList nodeList = student.getChildNodes();
System.out.println("第"+(i + 1)+"个student节点的子节点数量:"+nodeList.getLength());
//发现输出的结果是9
//是因为在<name>节点的前后,有空格与换行符存在,前后两个,就是两个文本节点
//文本节点+name节点+文本节点=9
for (int j = 0; j < nodeList.getLength(); j++) {
//获取每一个子节点对象
Node node = nodeList.item(j);
//输出每个子节点的属性与属性值
System.out.println("第"+(j+1)+"个节点名为:"+node.getNodeName()+"---值为:"+node.getNodeValue()+"---");
//所以能看到控制台输出时,当属性为#text时,值是空格加换行符
//文本的节点名为:#text
//元素的节点名:就是尖括号中的元素名
//元素的nodeValue值就是开始标签与结束标签中间的文本内容
}
同样的方式可以再获得子节点的子节点
下面是DOM解析的完整代码
public class ResolveXMLDemo {
private static List<Student> data ;
public static void main(String[] args) {
blogDocumentDemo();
showData();
}
private static void showData() {
for (int i = 0; i < data.size(); i++) {
Student student = data.get(i);
System.out.println("student---id:"+student.getId()+"--name:"+student.getName());
}
}
private static void blogDocumentDemo() {
data = new ArrayList<>();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//第二步创建一个DocumentBuilder的对象
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//第三步:(可以传入绝对路径也可以传入相对路径)
//通过parse方法加载test.xml文件到当前目录下(这样就将文件中的数据信息加载到document对象上了)
//得到document对象,注意是:org.w3c包下的
org.w3c.dom.Document document = documentBuilder.parse("test.xml");
//下面是解析的步骤
//第一步,通过标签名获得标签(是所有student节点的集合)
NodeList studentList = document.getElementsByTagName("student");
//第二步,获取属性名属性值,遍历每一个student节点
for (int i = 0; i < studentList.getLength(); i++) {
//通过 item(i)方法 获取一个student的节点信息(索引都是从零开始的)
Node student = studentList.item(i);
Student studentEntity = new Student();
//遍历student节点中的属性
//先拿到student节点的所有属性的集合
NamedNodeMap attrs = student.getAttributes();
for (int j = 0; j < attrs.getLength(); j++) {
Node attr = attrs.item(j);//获得第j个属性
if(attr.getNodeName().equals("id")){
studentEntity.setId(attr.getNodeValue());
}
}
//获取student节点的子节点的内容
for (int j = 0; j < student.getChildNodes().getLength(); j++) {
//获取每一个子节点对象
Node node = student.getChildNodes().item(j);
//输出每个子节点的属性与属性值
String nodeName = node.getNodeName();
String nodeValue = node.getNodeValue();
switch (nodeName){
case "name":
studentEntity.setName(nodeValue);
break;
case "score":
studentEntity.setScore(nodeValue);
break;
case "like":
studentEntity.setLike(nodeValue);
break;
case "goodat":
studentEntity.setGoodAt(nodeValue);
break;
}
}
data.add(studentEntity);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}