XMLFactory

简介

整合了三种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多
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值