简介
整合了三种XML解析器,分别是Dom,Pull和Sax。可以从XML文件当中解析出对象,或者将对象转换成XML文件。
项目地址:https://gitee.com/huangbei1990/Dispatcher
XMLFactory作为Dispatcher项目当中的一个模块而存在。也可以直接将其打包成aar文件引用。
具体实现
代码架构如下图所示
- Parser解析接口
public interface Parser {
public List parse(InputStream inputStream , Class cl)throws Exception ;
}
将输入流按照参数cl的模板解析,最终得出cl的对象列表。
- Serializer序列化接口
public interface Serializer {
public String serialize(Object obj);
}
将对象obj序列化成xml格式的字符串。
- XMLFactory
集合各种解析和序列化方式,方便用户调用。
接下来主要看各种解析器的实现:
1.DomParser
注释所标出来的“位置1”,可以根据参数cl解析出类的信息,详细代码请在项目地址当中查看。
Dom解析器,需要将文档整个加载到内存当中,并通过节点去遍历。
public class DomParser implements Parser{
@Override
public List parse(InputStream inputStream, Class cl) throws Exception {
List list = new ArrayList();
try{
ClassMsg classMsg = new ClassMsg(cl);//位置1
//解析
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(inputStream);
Element rootElement = doc.getDocumentElement();
NodeList items = rootElement.getElementsByTagName(classMsg.getClassName());
for(int i=0;i<items.getLength();i++){
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for(int j=0;j<properties.getLength();j++){
Node property = properties.item(j);
String nodename = property.getNodeName();
if(classMsg.isProperty(nodename)) {
String value = property.getFirstChild().getNodeValue();
classMsg.addValue(nodename, value);
}
}
Object obj = classMsg.generateObj();
if(obj!=null) {
list.add(obj);
}
}
return list;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
2.PullParser
基于事件来进行相应的操作,需要自己去主动获取事件。
小巧轻便,解析速度快,很适合在Android上使用。
public class PullParser implements Parser{
@Override
public List parse(InputStream inputStream, Class cl) throws Exception {
List list = new ArrayList();
try{
ClassMsg classMsg = new ClassMsg(cl);
XmlPullParser parser = Xml.newPullParser(); //由android.util.Xml创建一个XmlPullParser实例
parser.setInput(inputStream, "UTF-8"); //设置输入流 并指明编码方式
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals(classMsg.getClassName())) {
classMsg.clearProperty();
}else if(classMsg.isProperty(name)){
eventType = parser.next();
classMsg.addValue(name,parser.getText());
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals(classMsg.getClassName())) {
list.add(classMsg.generateObj());
}
break;
}
eventType = parser.next();
}
return list;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
3.SaxParser
这是三个解析器当中代码量最大的一个,也是基于事件模式,会将事件发送给相应的回调函数当中。
Sax也非常适合在Android当中使用,不过代码量就会比Pull解析器大。
public class SaxParser extends DefaultHandler implements Parser {
private List list;
private StringBuilder builder;
private ClassMsg classMsg;
public SaxParser(){
list = new ArrayList();
builder = new StringBuilder();
}
@Override
public List parse(InputStream inputStream , Class cl) throws Exception {
this.classMsg = new ClassMsg(cl);
//解析inputstream
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputStream,this);
return list;
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
builder.setLength(0);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
builder.append(ch,start,length);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
classMsg.addValue(localName,builder.toString());
if(localName.equals(classMsg.getClassName())){//一个类解析完成
list.add(classMsg.generateObj());
}
}
}
Demo
待解析的xml如下所示
<Jumps>
<Jump>
<key>test01</key>
<path>com.example.huangbei.dispatcher.MainActivity</path>
</Jump>
<Jump>
<key>test02</key>
<path>com.example.huangbei.dispatcher.SecondActivity</path>
</Jump>
</Jumps>
Jump类如下所示
public class Jump {
private String key;
private String path;
public Jump(){
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public void clear(){
this.key = null;
this.path = null;
}
}
以下代码可以从XML文件当中解析出Jump对象列表。
InputStream inputStream = getAssets().open("jump.xml");
Parser parser = XMLFactory.getPullParser();
List<Jump> list = parser.parse(inputStream, Jump.class);
总结
解析器 | 特点 |
---|---|
Dom | 将文档整个读入内存,加载时间长,基于树形结构,可以用于遍历和检索 |
Pull | 基于事件模型,解析快速,代码量少,适合Android |
Sax | 基于事件模型,解析快速,代码量比pull多 |