1. 程式人生 > >使用SAX寫XML文件

使用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");
 }
}