(补充)各种解析方式的原理和优缺点
DOM解析方式:文档树对象的方式一次性加载进内存,对内存消耗较大,不适合大文件,但对节点的增删改查十分方便,只需根据根节点或待操作节点的父节点找到对应节点进行操作即可。
SAX解析方式:读取一行处理一行,解析速度快,节省内存,缺点是不适合增删改查,只适合读取
JAXP案例
一、需求:一个基本的学生成绩管理系统,用xml文档模拟数据库,要求能够向数据库实时增删改查学生成绩数据
二、需求分析:
1.需要分层定义和实现,在用户层由用户输入查询信息,在底层做好数据接收,异常抛出、处理和程序测试,保证在UI层不会出现未捕获和处理的异常,并能正确处理非法输入和操作信息不存在的情况,给用户一个良好的用户体验。
2.定义学生类封装id,name,scores等数据,定义学生工具类根据查询关键字进行各种学生信息处理,适当利用容器存储多个学生对象,层层抽取简化,在用户层抽取成只是简单接收和调用。
三、文档,各层接口和所用技术
(开发时逐步更新)
四、具体流程实现
1.xml文档和简单学生类:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam>
<student examid="222" idcard="111">
<name>张三</name>
<location>沈阳</location>
<grade>89</grade>
</student>
<student examid="444" idcard="333">
<name>李四</name>
<location>大连</location>
<grade>89</grade>
</student>
</exam>
根据文档设计学生类属性:
package cn.itcast.domain;
public class Student {
private String examid;
private String idcard;
private String name;
private String location;
private double grade;
/**
* @return the examid
*/
String getExamid() {
return examid;
}
/**
* @param examid the examid to set
*/
void setExamid(String examid) {
this.examid = examid;
}
/**
* @return the idcard
*/
String getIdcard() {
return idcard;
}
/**
* @param idcard the idcard to set
*/
void setIdcard(String idcard) {
this.idcard = idcard;
}
/**
* @return the name
*/
String getName() {
return name;
}
/**
* @param name the name to set
*/
void setName(String name) {
this.name = name;
}
/**
* @return the location
*/
String getLocation() {
return location;
}
/**
* @param location the location to set
*/
void setLocation(String location) {
this.location = location;
}
/**
* @return the grade
*/
double getGrade() {
return grade;
}
/**
* @param grade the grade to set
*/
void setGrade(double grade) {
this.grade = grade;
}
}
2.学生工具类分析:利用JAXP根据输入的关键字信息实现对xml文档的增删改查,学生数据是一个整体,无论是接收处理还是返回数据都要封装成Student对象,方便于对数据的调用和封装存放(可能删除会稍有不同,直接判断节点属性值删除对应节点即可)
从学生工具类中剥离、抽取出的主要功能:各种处理需求中JAXP对xml的一些统一操作封装成工具类抽取出来,一个特殊的用于信息返回目的的自定义异常类(后面会发觉到)
抽取出操作xml文档的工具类:
public class XmlUtils {
//用xml文档创建Document对象
public static Document getDocument(String filename) throws Exception{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
return builder.parse(filename);
}
//将Document对象写回xml文档
public static void write2XML(Document document,String filename) throws Exception{
TransformerFactory factory=TransformerFactory.newInstance();
Transformer tf=factory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream(filename)));
}
}
一个特殊的用于信息返回目的的自定义异常类(后面用到):
package cn.itcast.exception;
public class StudentNotExistsException extends Exception {
public StudentNotExistsException() {
super();
// TODO Auto-generated constructor stub
}
public StudentNotExistsException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public StudentNotExistsException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public StudentNotExistsException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
学生工具类具体实现:所用技术:JAXP和w3c.dom
package cn.itcast.dao;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import cn.itcast.domain.Student;
import cn.itcast.exception.StudentNotExistsException;
import cn.itcast.xmlutils.XmlUtils;
public class StudentDao {
private String filename = "src/exam.xml";
public StudentDao(String filename) {
this.filename = filename;
}
/**
* @param filename
* the filename to set
*/
void setFilename(String filename) {
t