使用SAX写XML文档

http://blog.sina.com.cn/s/blog_647275f80100gie9.html(完整引用)


在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<String, String> map, String objectElement)
   throws SAXException {
  Set<String> 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, String> map = new HashMap<String, String>();
   map.put("id", "20050505");
   map.put("name", "zhaobenshan");
   map.put("age", "21");
   map.put("classes", "Act051");

   xml.write(map, "student");
   
   map = new HashMap<String, String>();
   map.put("id", "20050506");
   map.put("name", "songdandan");
   map.put("age", "20");
   map.put("classes", "Act052");
   
   xml.write(map, "student");
   
   map = new HashMap<String, String>();
   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

<?xml version="1.0" encoding="UTF-8" ?>
<students>
 <student>
  <id>20050505</id>
  <name>zhaobenshan</name>
  <age>21</age>
  <desc>
   <class>Act051</class>
   <major>Art</major>
  </desc>
 </student>

 <student>
  <id>20050506</id>
  <name>songdandan</name>
  <age>20</age>
  <desc>
   <class>Act052</class>
   <major>Art</major>
  </desc>
 </student>

 <student>
  <id>20050507</id>
  <name>fanchushi</name>
  <age>21</age>
  <desc>
   <class>Act053</class>
   <major>Art</major>
  </desc>
 </student>
</students>


解析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, 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<String, String>();
  }
 }

 public static void main(String[] args) {
  ReadXml xml = new ReadXml("student");
  xml.reader("c:\\students.xml");
 }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值