本文先使用DOM方式写一个简单地小例子,亲测可以运行,然后在末尾分析其优缺点。
1.准备
<?xml version="1.0" encoding="UTF-8"?>
<student_info>
<student id="1">
<name>张三</name>
<gender>男</gender>
<age>16</age>
</student>
<student id="2">
<name>李四</name>
<gender>女</gender>
<age>15</age>
</student>
</student_info>
- 由于是Maven工程,所有xml都存放在src/main/resources下面
2.编码
- Bean文件:StudentBean.java
public class StudentBean {
private String id;
private String name;
private String gender;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "StudentBean [id=" + id + ",name=" + name + ",gender=" + gender + ",age=" + age + "]";
}
}
- XML读写类:DOMTest.java
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import bean.StudentBean;
public class DOMTest {
// 创建一个Vector来保存每个student对象
public static Vector<StudentBean> studentsVector = new Vector<StudentBean>();
public static void main(String[] args) {
// 创建一个Vector来存放StudentBean对象
Vector<StudentBean> v = readXMLFile("src/main/resources/student.xml");
Iterator<StudentBean> it = v.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
writeXMLFile("src/main/resources/college.xml");
updateXMLFile("src/main/resources/student.xml");
}
// 从XML文件中读数据
public static Vector<StudentBean> readXMLFile(String fileName) {
// 为解析XML做准备,首先创建DocumentBuilderFactory实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
try {
// 指定DocumentBuilder
db = dbf.newDocumentBuilder();
doc = db.parse(fileName);
} catch (ParserConfigurationException e) {
// 输出异常信息然后退出
e.printStackTrace();
System.exit(1);
} catch (SAXException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
// 下面开始解析XML文件过程
// 先取根元素
Element root = doc.getDocumentElement();
// 获取student个数
NodeList students = root.getElementsByTagName("student");
System.out.println("XML文件中有" + students.getLength() + "个对象!");
for (int i = 0; i < students.getLength(); i++) {
Element st = (Element) students.item(i);
// 创建一的StudentBean对象用来保存XML中学生的属性
StudentBean sb = new StudentBean();
// 获取student节点的属性值赋给Bean对象
// 注意,属性值是在节点括号里面的
sb.setId(st.getAttribute("id"));
// st是一个student节点,在这个节点内获取所有标记名为name的元素,保存为NodeList
NodeList names = st.getElementsByTagName("name");
// 单一student节点下只有一个name节点,所以只需要取names第一个元素即可
Element name = (Element) names.item(0);
Node t = name.getFirstChild();
sb.setName(t.getNodeValue());
NodeList genders = st.getElementsByTagName("gender");
Element gender = (Element) genders.item(0);
Node n = gender.getFirstChild();
sb.setGender(n.getNodeValue());
NodeList ages = st.getElementsByTagName("age");
Element age = (Element) ages.item(0);
Node g = age.getFirstChild();
sb.setAge(Integer.parseInt(g.getNodeValue()));
studentsVector.add(sb);
}
return studentsVector;
}
// 将数据写入XML文件
public static void writeXMLFile(String fileName) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
doc = db.newDocument();
// 创建根元素
Element root = doc.createElement("student_info");
// 将根元素添加到文档上
doc.appendChild(root);
for (int i = 0; i < studentsVector.size(); i++) {
// 取出studentBean对象
StudentBean s = (StudentBean) studentsVector.get(i);
// 创建student元素
Element stu = doc.createElement("student");
// 为该student元素增加属性
stu.setAttribute("id",s.getId());
// 将stu添加到root元素上
root.appendChild(stu);
// 创建name元素
Element name = doc.createElement("name");
stu.appendChild(name);
Text tname = doc.createTextNode(s.getName());
name.appendChild(tname);
// 创建gender元素
Element gender = doc.createElement("gender");
stu.appendChild(gender);
Text tgender = doc.createTextNode(s.getGender());
gender.appendChild(tgender);
// 创建age元素
Element age = doc.createElement("age");
stu.appendChild(age);
Text tage = doc.createTextNode(s.getAge().toString());
age.appendChild(tage);
// 开始将文档树写入XML文件
try {
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter out = new OutputStreamWriter(fos);
callWriteXMLFile(doc,out,"UTF-8");
out.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("数据已经写入XML文档!");
}
// 修改XML文件中的某项内容
public static void updateXMLFile(String fileName) {
// 为解析XML做准备,首先创建DocumentBuilderFactory实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
try {
// 指定DocumentBuilder
db = dbf.newDocumentBuilder();
doc = db.parse(fileName);
} catch (ParserConfigurationException e) {
// 输出异常信息然后退出
e.printStackTrace();
System.exit(1);
} catch (SAXException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
// 先取根元素
Element root = doc.getDocumentElement();
NodeList students = root.getElementsByTagName("student");
// 修改第二个学生的信息
Element st = (Element) students.item(1);
NodeList genders = st.getElementsByTagName("gender");
Element gender = (Element) genders.item(0);
Node n = gender.getFirstChild();
// 修改该节点的值
n.setNodeValue("中");
try {
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter out = new OutputStreamWriter(fos);
callWriteXMLFile(doc,"UTF-8");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("XML文档数据已经修改!");
}
// 对XML文件进行写和改操作后,需要保存XML文件才能生效
public static void callWriteXMLFile(Document doc,OutputStreamWriter out,String encoding) {
Source source = new DOMSource(doc);
Result result = new StreamResult(out);
try {
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.setOutputProperty(OutputKeys.ENCODING,encoding);
xformer.transform(source,result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
}
3.运行结果
控制台输出为:
程序自行新建的XML文件college.xml为:
<?xml version="1.0" encoding="UTF-8"?>
<student_info>
<student id="1">
<name>张三</name>
<gender>男</gender>
<age>16</age>
</student>
<student id="2">
<name>李四</name>
<gender>女</gender>
<age>15</age>
</student>
</student_info>
程序修改后的student.xml为:
<?xml version="1.0" encoding="UTF-8"?>
<student_info>
<student id="1">
<name>张三</name>
<gender>男</gender>
<age>16</age>
</student>
<student id="2">
<name>李四</name>
<gender>中</gender>
<age>15</age>
</student>
</student_info>
4.结束
DOM解析方式是把整个XML文档当成一个对象来处理,在解析的时候会把整个文档读入到内存中。它是基于树的结构,通常需要加载整个文档并且构造DOM树,然后才能工作。 优点:由于整棵树都在内存中,所以具有随机访问的优点。 缺点:整个文档必须一次性解析完,不太适合较大的文档解析。