Android学习之旅(1)——XML的写入与解析

来源:互联网 发布:天谕萝莉数据 编辑:程序博客网 时间:2024/05/14 15:20

呀哈哈,今天端午节嘛,呀天气不错嘛,写篇文章记录一下!
今天是进公司的第一个礼拜的周末(端午节多放一天假哟^_^),闲着无聊……咳咳就写写这礼拜都做了些什么吧!
首先!公司用的是Ubuntu系统,对于我这个资深Windows症候群玩家来说,完全看不懂他在做什么啊!啊喂!咳咳算了这部分之后再说…..
先来讲讲礼拜五师傅让我做的一个Demo,XML的数据写入和解析(这只是一部分,剩下的数据库操作下周完成)。
正文开始:
1.既然是XML写入和解析,首先需要有对象!(咳咳单身狗别想歪了)
建立一个User对象(实体类),设置属性其属性
private int id;
private String name;
private String number;
private long date;//存储时间的毫秒数
2.设置一个List随便放点数据进去
users = new ArrayList();
users.add(new User(1,”张某某”,”15088888888”,System.currentTimeMillis()));
users.add(new User(2,”郭猴猴”,”18988888888”,System.currentTimeMillis()));
3.这里写一个方法用于将users转成XML输出至sd卡(记得给模拟器分配SD卡空间)

    public void saveXML(List<User> users){        String sdState = Environment.getExternalStorageState();//sd卡状态        String path = Environment.getExternalStorageDirectory().toString();//sd卡根目录        if(sdState.equals(Environment.MEDIA_MOUNTED)){//如果sd卡可用            XmlSerializer serializer = Xml.newSerializer();//Xml输出类            File file = new File(path,"test01_sql.xml");//文件名自己取            FileOutputStream os;            try {                os = new FileOutputStream(file);                serializer.setOutput(os, "UTF-8");                serializer.startDocument("UTF-8", true);                serializer.startTag(null, "USERS");//设置标签                serializer.attribute(null, "xmlns", "http://test01_sql");//标签属性                for (User user : users) {//遍历所有user                    serializer.startTag(null, "USER");//开始标签                    serializer.startTag(null, "ID");                    serializer.text(user.getid()+"");//标签之间的内容                    serializer.endTag(null, "ID");                    serializer.startTag(null, "NAME");                    serializer.text(user.getName()+"");                    serializer.endTag(null, "NAME");                    serializer.startTag(null, "NUMBER");                    serializer.text(user.getNumber()+"");                    serializer.endTag(null, "NUMBER");                    serializer.startTag(null, "DATE");                    serializer.text(user.getDate()+"");                    serializer.endTag(null, "DATE");                    serializer.endTag(null, "USER");//结束标签                }                serializer.endTag(null, "USERS");                serializer.endDocument();                os.close();                System.out.println("XML添加成功\n"+path+"/test01_sql.xml");            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();                System.out.println("XML添加失败");            }        }    }

4.检测一下XML是否生成成功

File f = new File(url);//url是文件路径        InputStream is;        if(f.exists()){            try {                is = new FileInputStream(f);                byte[] b = new byte[(int)f.length()];                is.read(b);                System.out.println(new String(b));//打印在控制台上                is.close();            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }

5.创建XML解析类(SAX解析)

public class XML_SAX extends DefaultHandler{    String element;//标签暂存    List<User> users;    User user;    StringBuffer jsonStringBuffer;      int frontBlankCount = 0;      public XML_SAX(){        jsonStringBuffer = new StringBuffer();    }    public List<User> getUsers(){        return users;    }    private String toBlankString(int count){          StringBuffer buffer = new StringBuffer();          for(int i = 0;i<count;i++)              buffer.append("    ");          return buffer.toString();      }      /*      * 接收字符数据的通知。      * 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue)      */      @Override    public void characters(char[] ch, int begin, int length)            throws SAXException {        StringBuffer buffer = new StringBuffer();          for(int i = begin ; i < begin+length ; i++){              switch(ch[i]){              case '\\':buffer.append("\\\\");break;              case '\r':buffer.append("\\r");break;              case '\n':buffer.append("\\n");break;              case '\t':buffer.append("\\t");break;              case '\"':buffer.append("\\\"");break;              default : buffer.append(ch[i]);               }          }          if(element.equals("ID")){            user.setid(Integer.parseInt(buffer.toString()));        }else if(element.equals("NAME")){            user.setName(buffer.toString());        }else if(element.equals("NUMBER")){            user.setNumber(buffer.toString());        }else if(element.equals("DATE")){            user.setDate(Long.parseLong(buffer.toString()));            users.add(user);//date是最后一项        }        System.out.println(this.toBlankString(this.frontBlankCount)+                  ">>> characters("+length+"): "+buffer.toString());    }    /*      * 接收文档的结尾的通知。      */     @Override    public void endDocument() throws SAXException {         System.out.println(this.toBlankString(--this.frontBlankCount)+                      ">>> end document");      }    /*      * 接收文档的结尾的通知。      * 参数意义如下:      *    uri :元素的命名空间      *    localName :元素的本地名称(不带前缀)      *    qName :元素的限定名(带前缀)      *       */      @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        System.out.println(this.toBlankString(--this.frontBlankCount)+                  ">>> end element : "+qName+"("+uri+")");    }     /*      * 结束前缀 URI 范围的映射。      */      @Override    public void endPrefixMapping(String prefix) throws SAXException {        System.out.println(this.toBlankString(--this.frontBlankCount)+                  ">>> end prefix_mapping : "+prefix);      }    /*      * 接收可恢复的错误的通知      */     @Override    public void error(SAXParseException e) throws SAXException {        System.err.println("Error ("+e.getLineNumber()+","                  +e.getColumnNumber()+") : "+e.getMessage());      }    /*      * 接收不可恢复的错误的通知。      */     @Override    public void fatalError(SAXParseException e) throws SAXException {         System.err.println("FatalError ("+e.getLineNumber()+","                      +e.getColumnNumber()+") : "+e.getMessage());     }    /*      * 接收元素内容中可忽略的空白的通知。      * 参数意义如下:      *     ch : 来自 XML 文档的字符      *     start : 数组中的开始位置      *     length : 从数组中读取的字符的个数      */      @Override    public void ignorableWhitespace(char[] ch, int begin, int length)            throws SAXException {        StringBuffer buffer = new StringBuffer();          for(int i = begin ; i < begin+length ; i++){              switch(ch[i]){                  case '\\':buffer.append("\\\\");break;                  case '\r':buffer.append("\\r");break;                  case '\n':buffer.append("\\n");break;                  case '\t':buffer.append("\\t");break;                  case '\"':buffer.append("\\\"");break;                  default : buffer.append(ch[i]);               }          }          System.out.println(this.toBlankString(                this.frontBlankCount)+">>> ignorable whitespace("+length+"): "+buffer.toString());      }     /*      * 接收注释声明事件的通知。      * 参数意义如下:      *     name - 注释名称。      *     publicId - 注释的公共标识符,如果未提供,则为 null。      *     systemId - 注释的系统标识符,如果未提供,则为 null。      */      @Override    public void notationDecl(String name, String publicId, String systemId)            throws SAXException {        System.out.println(">>> notation declare : (name = "+name                  +",systemId = "+publicId                  +",publicId = "+systemId+")");      }    /*      * 接收处理指令的通知。      * 参数意义如下:      *     target : 处理指令目标      *     data : 处理指令数据,如果未提供,则为 null。      */     @Override    public void processingInstruction(String target, String data)            throws SAXException {        System.out.println(this.toBlankString(this.frontBlankCount)+">>> process instruction : (target = \""                  +target+"\",data = \""+data+"\")");      }    /*      * 允许应用程序解析外部实体。      * 解析器将在打开任何外部实体(顶级文档实体除外)前调用此方法      * 参数意义如下:      *     publicId : 被引用的外部实体的公共标识符,如果未提供,则为 null。      *     systemId : 被引用的外部实体的系统标识符。      * 返回:      *     一个描述新输入源的 InputSource 对象,或者返回 null,      *     以请求解析器打开到系统标识符的常规 URI 连接。      */    @Override    public InputSource resolveEntity(String publicId, String systemId)            throws IOException, SAXException {        // TODO Auto-generated method stub        return null;    }     /*      * 接收用来查找 SAX 文档事件起源的对象。      * 参数意义如下:      *     locator : 可以返回任何 SAX 文档事件位置的对象      */      @Override    public void setDocumentLocator(Locator locator) {        System.out.println(this.toBlankString(this.frontBlankCount)+                  ">>> set document_locator : (lineNumber = "+locator.getLineNumber()                  +",columnNumber = "+locator.getColumnNumber()                  +",systemId = "+locator.getSystemId()                  +",publicId = "+locator.getPublicId()+")");     }     /*      * 接收跳过的实体的通知。      * 参数意义如下:       *     name : 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头,      *            如果它是外部 DTD 子集,则将是字符串 "[dtd]"      */      @Override    public void skippedEntity(String name) throws SAXException {         System.out.println(this.toBlankString(this.frontBlankCount)+                      ">>> skipped_entity : "+name);      }     /*      * 接收文档的开始的通知。      */      @Override    public void startDocument() throws SAXException {         System.out.println(this.toBlankString(this.frontBlankCount++)+                      ">>> start document ");      }    /*      * 接收元素开始的通知。      * 参数意义如下:      *    uri :元素的命名空间      *    localName :元素的本地名称(不带前缀)      *    qName :元素的限定名(带前缀)      *    atts :元素的属性集合      */      @Override    public void startElement(String uri, String localName, String qName,            Attributes attributes) throws SAXException {         if(qName.equals("USERS")){             users = new ArrayList<User>();         }else if(qName.equals("USER")){             user = new User();         }else if(qName.equals("ID")||qName.equals("NAME")||                 qName.equals("NUMBER")||qName.equals("DATE") ){             element = qName;         }         System.out.println(this.toBlankString(this.frontBlankCount++)+                      ">>> start element : "+qName);      }    /*      * 开始前缀 URI 名称空间范围映射。      * 此事件的信息对于常规的命名空间处理并非必需:      * 当 http://xml.org/sax/features/namespaces 功能为 true(默认)时,      * SAX XML 读取器将自动替换元素和属性名称的前缀。      * 参数意义如下:      *    prefix :前缀      *    uri :命名空间      */      @Override    public void startPrefixMapping(String prefix, String uri)            throws SAXException {        System.out.println(this.toBlankString(this.frontBlankCount++)+                  ">>> start prefix_mapping : xmlns:"                 +"\""+uri+"\"");      }     /*      * 接收未解析的实体声明事件的通知。      * 参数意义如下:      *     name - 未解析的实体的名称。      *     publicId - 实体的公共标识符,如果未提供,则为 null。      *     systemId - 实体的系统标识符。      *     notationName - 相关注释的名称。      */     @Override    public void unparsedEntityDecl(String name, String publicId,            String systemId, String notationName) throws SAXException {        System.out.println(">>> unparsed entity declare : (name = "+name                  +",systemId = "+publicId                  +",publicId = "+systemId                  +",notationName = "+notationName+")");      }      /*      * 接收不可恢复的错误的通知。      */      @Override    public void warning(SAXParseException e) throws SAXException {        System.err.println("Warning ("+e.getLineNumber()+","                  +e.getColumnNumber()+") : "+e.getMessage());      }}

简单来说就是继承了DefaultHandler,重写其方法,其中方法会将XML内容提取出来,大家稍微运行下代码就看得懂了,输出是有层次的。
期间我还将解析出来的数据存在了List里在使用解析时可以将User内容输出(为了数据库操作准备的)

6.使用XML解析类

System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver"); //运行之前需要注册 Sax 驱动(android中需要)XML_SAX dh = new XML_SAX(); //创建处理xml的处理器 XMLReader reader;//创建一个XML解析器(通过SAX方式读取解析XML)  try {    reader = XMLReaderFactory.createXMLReader();    /*      * 设置解析器的相关特性      *     http://xml.org/sax/features/validation = true 表示开启验证特性      *     http://xml.org/sax/features/namespaces = true 表示开启命名空间特性     */              reader.setFeature("http://xml.org/sax/features/validation",true);                     reader.setFeature("http://xml.org/sax/features/namespaces",true);              //设置XML解析器的处理器              reader.setDTDHandler(dh);            reader.setContentHandler(dh);            reader.setEntityResolver(dh);            reader.setErrorHandler(dh);            //解析url对应的xml文档             System.out.println("开始解析");            reader.parse(new InputSource(new FileReader(url)));             System.out.println("解析结束");            List<User> users_x = dh.getUsers();            for (User use_x : users_x) {                System.out.println("User:"+use_x.getid()+":"+use_x.getName()+":"+use_x.getNumber()+":"+use_x.getDate());            }//输出XML中的User中的属性        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }   

总结:
基本就是这样了吧!应该没啥问题!第一次写这种东西!咳咳。。。!我没紧张!那下次再给大家继续吐槽!谢谢大家!
(啊喂!好像有人看一样!(σ`д′)σ(゚Д゚*)ノ)

0 0
原创粉丝点击