DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的事件模型。
DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。
SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
DOM [树型结构] SAX [事件驱动型]
于是采用SAX解析!网上有人写过,但存在些问题,于是自己做了修改测试!放出代码如下:
[java] view plain copy
package logame.core
import java.util.ArrayList
import java.util.HashMap
import java.util.LinkedList
import java.util.List
import java.util.Map
import java.util.Stack
import org.xml.sax.Attributes
import org.xml.sax.SAXException
import org.xml.sax.helpers.DefaultHandler
/**
* .plist配置文件的解析器
*
* @author afly
*
*/
public class PlistHandler extends DefaultHandler {
private boolean isRootElement = false
private boolean keyElementBegin = false
private String key
Stack<Object>stack = new Stack<Object>()
private boolean valueElementBegin = false
private Object root
@SuppressWarnings("unchecked")
public HashMap<String, Object>getMapResult() {
return (HashMap<String, Object>) root
}
@SuppressWarnings("unchecked")
public List<Object>getArrayResult() {
return (List<Object>) root
}
@Override
public void startDocument() throws SAXException {
System.out.println("开始解析")
}
@Override
public void endDocument() throws SAXException {
System.out.println("结束解析")
}
@SuppressWarnings("unchecked")
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// System.out.println(uri+"startElement:"+qName)
if ("plist".equals(qName)) {
isRootElement = true
}
if ("dict".equals(qName)) {
if (isRootElement) {
stack.push(new HashMap<String, Object>())// 压栈
isRootElement = !isRootElement
} else {
Object object = stack.peek()
HashMap<String, Object>dict = new HashMap<String, Object>()
if (object instanceof ArrayList)
((ArrayList<Object>) object).add(dict)
else if (object instanceof HashMap)
((HashMap<String, Object>) object).put(key, dict)
stack.push(dict)
}
}
if ("key".equals(qName)) {
keyElementBegin = true
}
if ("true".equals(qName)) {
HashMap<String, Object>parent = (HashMap<String, Object>) stack.peek()
parent.put(key, true)
}
if ("false".equals(qName)) {
HashMap<String, Object>parent = (HashMap<String, Object>) stack.peek()
parent.put(key, false)
}
if ("array".equals(qName)) {
if (isRootElement) {
ArrayList<Object>obj = new ArrayList<Object>()
stack.push(obj)
isRootElement = !isRootElement
} else {
HashMap<String, Object>parent = (HashMap<String, Object>) stack.peek()
ArrayList<Object>obj = new ArrayList<Object>()
stack.push(obj)
parent.put(key, obj)
}
}
if ("string".equals(qName)) {
valueElementBegin = true
}
}
/*
* 字符串解析(non-Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@SuppressWarnings("unchecked")
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("characters:")
if (length >0) {
if (keyElementBegin) {
key = new String(ch, start, length)
System.out.println("key:" + key)
}
if (valueElementBegin) {
if (HashMap.class.equals(stack.peek().getClass())) {
HashMap<String, Object>parent = (HashMap<String, Object>) stack.peek()
String value = new String(ch, start, length)
parent.put(key, value)
} else if (ArrayList.class.equals(stack.peek().getClass())) {
ArrayList<Object>parent = (ArrayList<Object>) stack.peek()
String value = new String(ch, start, length)
parent.add(value)
}
System.out.println("value:" + new String(ch, start, length))
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("plist".equals(qName)) {
}
if ("key".equals(qName)) {
keyElementBegin = false
}
if ("string".equals(qName)) {
valueElementBegin = false
}
if ("array".equals(qName)) {
root = stack.pop()
}
if ("dict".equals(qName)) {
root = stack.pop()
}
}
}
调用也相对比较简单:
[java] view plain copySAXParserFactory factorys = SAXParserFactory.newInstance()
SAXParser saxparser = factorys.newSAXParser()
PlistHandler plistHandler = new PlistHandler()
saxparser.parse(uri, plistHandler)
HashMap<String, Object>hash = plistHandler.getMapResult()
ArrayList<Object>array = (ArrayList<Object>)plistHandler.getArrayResult()
返回可以是一个 dict 也可以是一个array根据自己的格式获得。
synchronized 方法是将多条操作共享数据的线程代码封装起来,当有线程在执行代码的时候。其他线程不可以参与进来。
必须要当前线程把这些代码执行完后。其他线程才能进来。参与运算。
你要不就把同步删了,,要不就是你看哈你的线程调用该方法的时候 是不是出错了