package com.popo.xml;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.dom4j.io.DOMReader;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SAXParserFactory sf = SAXParserFactory.newInstance();
MyDefaultHandler df = new MyDefaultHandler();
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<data>"+
"<grade gredenum='gd1'>" +
" <class classnum='cl1'>" +
" <std name='xiaohong' age='16' />" +
" <std name='xiaoming' age='18' > =========================================================</std>" +
" <teacher name='tch_li' cource='chemistry'/>" +
" <teacher name='tch_jia' cource='physics'/>"+
" </class> " +
"</grade >"+
"<grade gredenum='gd2'>" +
" <class classnum='cl1'>" +
" <std name='monkeysun' age='530' />" +
" <std name='bajiepig' age='360' />"+
" <std name='cleanwu' age='320' />"+
" </class> " +
" <class classnum='cl2'>" +
"aafafafa" +
"</class>" +
"</grade >"+
"</data>"
;
/**
* "<grade n='2'>" +
" <class n=1>" +
" <std name='2l' age='22' />" +
" <std name='23' age='23' />"+
" </class> " +
" <class n=2>" +
" <std name='2l' age='22' />" +
" <std name='23' age='23' />"+
" </class>"+
"</grade >" +
*/
try {
SAXParser sp = sf.newSAXParser();
StringBufferInputStream in = new StringBufferInputStream(xml);
sp.parse(in, df);
System.out.println();
Data data = df.root;
System.out.println(data);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 设计的数据对象结构
* @author liboliu
*
*/
class Data{
//Node的名字
public String name=null;
//包含的数据 此数据应该与son互斥
public String data=null;
//属性
public HashMap<String, String> attr= null;
//子数据
public HashMap<String,ArrayList<Data>> son=null;
//对象翻译为XML
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
//node名字
sb.append("<"+name+" ");
//属性
if(attr!=null){
Set<String> keys = attr.keySet();
Iterator<String> it = keys.iterator();
while(it.hasNext()){
String key_ = it.next();
sb.append(" "+key_+"="+ attr.get(key_)+" ");
}
}
sb.append(" >\n");
//包含的数据或子项
if(son!=null){
Set<String> keys =son.keySet();
Iterator<String> it = keys.iterator();
while(it.hasNext()){
String key_ = it.next();
ArrayList<Data> sonData = son.get(key_);
for(Data d :sonData){
sb.append(d);
}
}
}
if(data!=null){
sb.append(data+"\n");
}
//结束
sb.append("</"+name+">\n");
return sb.toString();
}
}
class MyDefaultHandler extends DefaultHandler{
LinkedList<Data> stack =null;
Data parent = null;
Data self =null;
Data root =null;
int step=0;
LinkedList<Object> lo = new LinkedList<Object>();
boolean newDowcument = true;
public MyDefaultHandler() {
super();
// TODO Auto-generated constructor stub
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
//释放
stack=null;
parent=null;
self=null;
super.endDocument();
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
//解析完后自己出栈
stack.removeFirst();
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
//初始化 root linklist
root = new Data();
//初始话栈
stack= new LinkedList<Data>();
//把root进栈
stack.addFirst(root);
super.startDocument();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
//创建自己
self = new Data();
self.name=qName;
//获取父对象这里应该 出栈后 在入栈 但是用 linkedList 直接获取栈顶数据 就不用 进行出入栈操作了
parent = stack.peekFirst();
//自己进栈
stack.addFirst(self);
//把自己添加到parent里面去
addSelfInParent(self,parent,qName);
//填充属性
// System.out.println("uri="+uri+",localName:"+localName+",qName:"+qName);
int attributesl =attributes.getLength();
if(attributesl>0){
self.attr = new HashMap<String, String>();
}
for(int i=0;i<attributesl;i++){
self.attr.put(attributes.getLocalName(i), attributes.getValue(i));
}
super.startElement(uri, localName, qName, attributes);
}
/**
*
* @param self
* @param parent
* @param key
*/
@SuppressWarnings("unchecked")
private void addSelfInParent(Data self,
Data parent,String key) {
// TODO Auto-generated method stub
if(parent.son==null){
parent.son= new HashMap<String, ArrayList<Data>>();
ArrayList<Data> d = new ArrayList<Data>();
parent.son.put(key, d);
d.add(self);
}else{
if(parent.son.containsKey(key)){
parent.son.get(key).add(self);
}else{
ArrayList<Data> d = new ArrayList<Data>();
parent.son.put(key, d);
d.add(self);
}
}
}
@Override
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
// TODO Auto-generated method stub
self.data=new String(arg0,arg1,arg2);
super.characters(arg0, arg1, arg2);
}
}
这个是使用SAX将XML解析成对象 用到了栈