安卓解析XML文件系列1:使用SAX方式

来源:互联网 发布:骑士比赛数据统计 编辑:程序博客网 时间:2024/04/30 07:15
HTTP数据组织方式:

HTML方式、XML方式、JSON方式

XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言)。


Android中,解析XML数据的三种方式:
1.DOM(org.w3c.dom)
"文档对象模型"方式,解析完的XML将生成一个树状结构的对象。
2.SAX(org.xml.sax)
SimpleAPI for XML,以事件的形式通知程序,对XML进行解析。
3.XMLPULL(org.xmlpull.v1)

类似于SAX方式,程序以“拉取”得方式对XML进行解析。


SAX是一种以事件驱动的XMLapi,由它定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,简单的讲,它解析速度快,占用内存少的解析器。这种解析器比较适合android等移动设备。


使用SAX的优点是:
因为SAX的优势是流的方式处理,当遇到一个标签的时候,并不会记录下当前所碰到的标签。

也就是说,startEelment方法中,你所知道的信息,仅仅是当前的签名的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元素与其他结构相关的信息,都是不知道的。

使用SAX方式解析XML文件是我们经常使用的方式之一,下面我们来分享一下它的使用方法。

这个例子实现的是使用SAX方式解析XML文件,将web上的一个xml文件解析出语义。

整体思路:新建一个java工程,定义一个MyHandler类,继承DefaultHandler类,在里面定义一个HashMap对象,存储单个解析的完整对象,定义一个List对象,存储所有的解析对象,定义三个字符串对象,分别表示正在解析的元素标签currentTag、解析当前元素的值currentValue、解析当前的节点名称nodeName,在构造方法中给节点名称赋值,写一个getList方法,返回List对象,重写这个类里面的方法,startDocument方法当读到第一个开始标签的时候会触发,在这个方法中创建一个List对象,startElement方法当解析到开始元素的时候会触发,在这个方法中如果是解析的当前节点,则创建一个Map对象,如果Map对象不等于空的话,把解析的值放入Map对象中,把qName赋值给currentTag,characters方法当读取文档节点内容的时候会触发,在这个方法中如果正在解析的元素标签不等于空并且Map对象不等于空的话,把解析的字符串赋值给currentValue,如果currentValue不等于空或者换行符的话,把currentTag和currentValue放到Map对象中,并把currentTag和currentValue置空,endElement方法当遇到结束标志的时候会触发,在这个方法中如果nodeName等于qName的话,把Map对象加到List对象中,Map对象置空;定义一个HttpUtils类,在里面定义一个getXML方法,使用网址创建HttpURLConnection对象,设置它的超时时间、请求方式、获取服务器返回码,如果请求完成的话,返回请求结果的内容。定义一个SaxService类,在里面定义一个readXML方法,创建一个解析XML的工厂对象,解析XML,定义一个解析当前节点的MyHandler对象,返回对象中的内容。定义一个Test类,定义一个字符串类型变量path,用网络上解析的xml的网址对其赋值,对person节点进行解析,把解析的内容遍历输出。

MyHandler.java文件:

   public class MyHandler extends DefaultHandler {private HashMap<String, String> map=null;//存储单个解析的完整对象private List<HashMap<String, String>> list=null;//存储所有的解析对象private String currentTag=null;//正在解析的元素标签private String currentValue=null;//解析当前元素的值private String nodeName=null;//解析当前的节点名称public MyHandler(String nodeName) {// TODO Auto-generated constructor stubthis.nodeName=nodeName;}   public List<HashMap<String, String>> getList() {return list;}//重写这个类里面的方法//解析到开始文档的时候会触发的事件@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stub//当读到第一个开始标签的时候,会触发这个方法list=new ArrayList<HashMap<String, String>>();}//解析到开始元素的时候会触发的事件    @Override    public void startElement(String uri, String localName, String qName,    Attributes attributes) throws SAXException {    // TODO Auto-generated method stub//    当遇到文档的开头的时候,调用这个方法    if(qName.equals(nodeName)){    map=new HashMap<String,String>();    }    if(attributes!=null&&map!=null){    for(int i=0;i<attributes.getLength();i++){    map.put(attributes.getQName(i), attributes.getValue(i));    }    }    currentTag=qName;    }//  读取文档节点内容的时候会触发的事件    @Override    public void characters(char[] ch, int start, int length)    throws SAXException {//    这个方法是用来处理xml文件所读取到的内容    if(currentTag!=null&&map!=null){    currentValue=new String(ch,start,length);    if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){    map.put(currentTag, currentValue);    }    }    currentTag=null;//把当前节点对应的值和标签设置为空    currentValue=null;    }    //  当我们把整个文档解析完成的时候触发的事件    @Override    public void endElement(String uri, String localName, String qName)    throws SAXException {//    遇到结束标志的时候会调用这个方法    if(qName.equals(nodeName)){    list.add(map);    map=null;    }    super.endElement(uri, localName, qName);    }}

HttpUtils.java文件:

public class HttpUtils {public HttpUtils() {// TODO Auto-generated constructor stub}public static InputStream getXML(String path){InputStream inputStream=null;try {URL url=new URL(path);if(url!=null){HttpURLConnection connection=(HttpURLConnection)url.openConnection();connection.setConnectTimeout(3000);connection.setDoInput(true);connection.setRequestMethod("GET");int code=connection.getResponseCode();if(code==200){inputStream=connection.getInputStream();}}} catch (Exception e) {// TODO: handle exception}return inputStream;}}

SaxService.java文件:

   public class SaxService {public SaxService() {// TODO Auto-generated constructor stub}public static List<HashMap<String, String>> readXML(InputStream inputStream,String nodeName){try {//创建一个解析XML的工厂对象SAXParserFactory spf=SAXParserFactory.newInstance();SAXParser parser=spf.newSAXParser();//解析XMLMyHandler handler=new MyHandler(nodeName);parser.parse(inputStream, handler);inputStream.close();return handler.getList();} catch (Exception e) {// TODO: handle exception}return null;}}
Test.java文件:
public static void main(String[] args) {// TODO Auto-generated method stub       String path="http://172.21.75.194:8080/myhttp/person.xml";//       从服务器端将xml文件取回之后以流的形式返回       InputStream inputStream=HttpUtils.getXML(path);       try {List<HashMap<String, String>> list=SaxService.readXML(inputStream, "person");for(HashMap<String, String> map:list){//使用增强for循环System.out.println(map.toString());}} catch (Exception e) {// TODO: handle exception}}




0 0
原创粉丝点击