XML解析方式总结 SAX编程 DOM4J编程
思维导图大纲
1.DOM解析和SAX解析的区别是 DOM解析是把文档全部加载进去内容,形成树状结构,可以做增删改操作,但是容易产生内存溢出,SAX解析边读边解析,基于事件驱动,查询速度快,但是不能做增删改操作。
2.JAXP是jdk中方法,但是dom4j是比较常用的jar包
3.SAX编程是我们只要编写事件处理的代码就行,解析器解析到那里默认调用对应方法。
1)解析器解析文本方法 SAXParser.parse(InputStream is, DefaultHandler)中的DefaultHandler就是我们的事件处理器 要继承的父类,重写其中的startElement(String uri, String localName, String qName,Attributes attributes) characters(char[] ch, int start, int length) endElement(String uri, String localName, String qName)方法,解析到的信 息作为参传给对应方法
2)解析到开始标签调用startElement,解析中间文本调用characters,解析到结束标签调用endElement
SAX原理图示
SAX例子代码
// 目的: 获取所有的作者,打印出来
public static void getAuthor() throws Exception
{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser paser = factory.newSAXParser();
//事件处理类作为参数传进去解析文本
paser.parse(new FileInputStream("src/test.xml"), new myHandler());
}
//继承的事件处理类
class myHandler extends DefaultHandler
{
//标志位
private boolean isAuthor = false;
//开始标签调用
public void startElement(String uri, String localName, String qName, Attributes
attributes)throws SAXException
{
if(qName == "作者")
{
this.isAuthor = true;
}
}
//文本内容调用
public void characters(char[] ch, int start, int length) throws SAXException
{
if(this.isAuthor)
{
System.out.println(new String(ch, start, length));
}
}
//是结束标签就调用
public void endDocument() throws SAXException
{
this.isAuthor = false;
}
}
DOM4J解析使用
1.导包 导入dom4j-1.6.1.jar包,如果要使用xpath的话,需要另外导入jaxen-1.1-beta-6.jar包。导包导到WebContent>WEB-INF>lib下它会自己Build Path,导到其他地方要自己右键Build Path
2.步骤是先 new SAXReader() ,调用SAXReader的read()方法读取xml,得到Document,Document必先获得根节点才能解析xml文件。另外,DOM4J必须是一层一层的解析,要想跃层找元素,要使用xpath(需要导入jaxen-1.1-beta-6.jar)。
3.Element的elements()返回的是一个list<Element>
4.增加节点都是从父节点调用方法增加子节点parent.addElement(String Tagname),放回添加的节点。添加根节点的话,用document调用addElement()方法。
5.删除节点的话,格式为parentNode.remove(sonNode)。
package com.xml.test;
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Dom4JTest
{
public static void main(String[] args) throws Exception
{
ConnectionData cd = new ConnectionData("src/class3.xml");
//创建文件
cd.createFile();
cd.addStu("李华", "男");
cd.addStu("张雅", "女");
cd.addStu("赵四", "男");
cd.delStu("李华");
cd.addStu("佩奇", "女");
}
}
class ConnectionData
{
private String path;
private Document document;
private int id = 0;
public ConnectionData()
{
}
public ConnectionData(String path) throws Exception
{
this.path = path;
//内存中创建文本
}
public void createFile()throws Exception
{
this.document = DocumentHelper.createDocument();
//文本中创建一个节点
this.document.addElement("三5班");
rewrite();
}
/**
* 添加节点
* @throws Exception
* @throws Exception
*/
public void addStu(String name, String gender) throws Exception
{
SAXReader reader = new SAXReader();
//读取文本
Document doc;
doc = reader.read(path);
//获取根节点
Element root = doc.getRootElement();
//添加根节点的子节点
Element stu = root.addElement("学生");
//添加学生信息
stu.addElement("学号").setText((++id)+"");
stu.addElement("姓名").setText(name);
stu.addElement("性别").setText(gender);
this.document = doc;
rewrite();
}
/**
* 删除节点
* @param name
* @throws Exception
*/
public void delStu(String name) throws Exception
{
SAXReader reader = new SAXReader();
//读取文本
Document doc = reader.read(path);
//获取根节点
Element root = doc.getRootElement();
List<Element> stus = root.elements();
for(int i=0; i < stus.size(); i++)
{
Element stu = stus.get(i);
Element ele = stu.element("姓名");
//比对字符串内容要调用equals方法,不能用==来比对引用
if( ele.getText().equals(name) )
{
//调用父节点删除子节点,层级关系用搞好
root.remove(stu);
this.document = doc;
rewrite();
}
}
}
/**
* 回写
*/
private void rewrite() throws Exception
{
//设置输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
//输出编码
format.setEncoding("UTF-8");
//构造回写类(XMLWriter)
XMLWriter writer = new XMLWriter(new FileOutputStream(path), format);
//将文档回写
writer.write(this.document);
//关闭流
writer.close();
}
}
操作结果: