在Java中,我们用得最多的读写xml文件的方式是DOM,但DOM是将整个xml以DOM树的形式加载到内存中,再对DOM树进行操作,这样虽然很方便,但是,如果该xml文件较大时,就会造成内存溢出,写入xml也存在此问题,关于DOM解析的例子网上一堆一堆的,在此不作介绍。
SAX是基于事件的方法,它很类似于标签库的处理机制,在标签开始、结束以及错误发生等等地方调用相应的接口实现方法,不是全部文档都读入内存。
SAX具有优异的性能和利用更少的存储空间特点。
示例如下:
写xml:
package xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
public class WriteXml {
SAXTransformerFactory fac =
(SAXTransformerFactory) SAXTransformerFactory
.newInstance();
private TransformerHandler handler = null;
private OutputStream outStream = null;
private String fileName;
private AttributesImpl atts;
private String rootElement;
public WriteXml(String fileName, String
rootElement) {
this.fileName = fileName;
this.rootElement =
rootElement;
init();
}
public void init() {
try {
handler =
fac.newTransformerHandler();
Transformer
transformer = handler.getTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING,
"UTF-8");//
//
设置输出采用的编码方式
transformer.setOutputProperty(OutputKeys.INDENT,
"yes");// 是否自动添加额外的空白
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"no");//
是否忽略xml声明
outStream
= new FileOutputStream(fileName);
Result
resultxml = new StreamResult(outStream);
handler.setResult(resultxml);
atts = new
AttributesImpl();
start();
} catch
(TransformerConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException
e) {
e.printStackTrace();
}
}
private void start() {
try {
handler.startDocument();
handler.startElement("",
"", rootElement, atts);
} catch (SAXException e)
{
e.printStackTrace();
}
}
public void
write(HashMap map,
String objectElement)
throws
SAXException {
Set
keys = map.keySet();
Iterator it =
keys.iterator();
if (objectElement != null)
{
handler.startElement("",
"", objectElement, atts);
}
while (it.hasNext()) {
String key =
(String) it.next();
String value
= map.get(key);
handler.startElement("",
"", key, atts);
handler.characters(value.toCharArray(),
0, value.length());
handler.endElement("",
"", key);
}
if (objectElement != null)
{
handler.endElement("",
"", objectElement);
}
}
public void end() {
try {
handler.endElement("",
"", rootElement);
handler.endDocument();//
文档结束,同步到磁盘
outStream.close();
} catch (SAXException e)
{
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
WriteXml xml = new
WriteXml("c:/student.xml", "students");
try {
HashMap
String> map = new HashMap
String>();
map.put("id",
"20050505");
map.put("name",
"zhaobenshan");
map.put("age",
"21");
map.put("classes",
"Act051");
xml.write(map,
"student");
map = new
HashMap();
map.put("id",
"20050506");
map.put("name",
"songdandan");
map.put("age",
"20");
map.put("classes",
"Act052");
xml.write(map,
"student");
map = new
HashMap();
map.put("id",
"20050507");
map.put("name",
"fanchushi");
map.put("age",
"21");
map.put("classes",
"Act051");
xml.write(map,
"student");
xml.end();
} catch (SAXException e)
{
e.printStackTrace();
}
}
}
生成的students.xml
?>
20050505
zhaobenshan
21
Act051
Art
20050506
songdandan
20
Act052
Art
20050507
fanchushi
21
Act053
Art
解析students.xml,将每个对象student封装到map中
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXml extends DefaultHandler {
private HashMap
String> map;// 存储对象的属性名和属性值
private StringBuffer currentPath = new
StringBuffer("/");
private String objElement;// 标识一个对象的标签
private String elementName;// 元素名称
public ReadXml(String objElement) {
this.objElement =
objElement;
}
public void reader(String pathfile) {
long start =
System.currentTimeMillis();
InputStream inStream =
null;
try {
inStream =
new FileInputStream(pathfile);
SAXParserFactory
saxfac = SAXParserFactory.newInstance();
SAXParser
saxParser = saxfac.newSAXParser();
saxParser.parse(inStream,
this);
} catch (FileNotFoundException
e) {
e.printStackTrace();
} catch
(ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e)
{
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
} catch
(IOException e) {
e.printStackTrace();
}
}
long end =
System.currentTimeMillis();
System.out.println("解析耗时:" +
(end - start));
}
StringBuffer text = new StringBuffer("");
@Override
public void characters(char[] ch, int start, int
length)
throws
SAXException {
if(map != null
&& elementName != null){
String
content = new String(ch, start, length);
if(content.trim().length()
> 0){
text.append(new
String(ch, start, length));
map.put(elementName,
text.toString());
}
}
}
@Override
public void endElement(String uri, String
localName, String qName)
throws
SAXException {
currentPath
.delete(currentPath.lastIndexOf(qName),
currentPath.length());
if (qName.equals(objElement))
{
// do
something for map
System.out.println("Parsed
and object: " + map);
}
elementName = null;
text = new
StringBuffer("");
}
@Override
public void startElement(String uri, String
localName, String qName,
Attributes
attributes) throws SAXException {
currentPath.append(qName +
"/");
elementName = qName;
if (qName.equals(objElement))
{
map = new
HashMap();
}
}
public static void main(String[] args) {
ReadXml xml = new
ReadXml("student");
xml.reader("c:\\students.xml");
}
}