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