XML文件的解析

  1. xml是可扩展标记语言
  2. html是用来显示数据的,而xml是用来存储数据的。
  3. 实体引用与CDATA区:&lt;代表的是<号,&gt;代表大于号>。<![CDATA[直接显示的内容]]>:与转意字符的用法一致。
  • xml文件的解析分为三种:DOM、SAX、PULL,DOM解析需要一次性加载完所有的内容,占用内存较大。所以一般使用较少
  • SAX工作原理:
  1. 读到最上层<students>标签则初始化list集合
  2. 读到<student>标签就开始读取其中的<name><age><phonenum>等子元素。
  3. 把student子元素中的值存入一个student对象中,然后添加到集合list中。
  4. 逐个取出。
  • SAX解析代码:具体事物是交由handle事件处理对象去执行的。(以students.xml文件为例)
          //创建解析工厂
          SAXParserFactory factory = SAXParserFactory.newInstance();
           //创建解析对象
          SAXParser parser = factory.newSAXParser();
           //创建事件处理对象
          HandlerForStudent handle = new HandlerForStudent();
          URL url = new URL("http://localhost:8080/TestTomcat/students.xml" );
          InputStream is = url.openStream();
     //handle对象不用去调用方法,在这里它会自动执行复写父类的所有方法。是一种回调的用法。
           parser.parse( is, handle);
          List<Student> list = handle.getList();
           for (Student student : list) {
              System. out.println( student);
          }
  • Handle类处理部分:分为四个方法,执行顺序如下1,2,3,4。除了1其他都是循环执行的。
  1.startDocument():文件开始函数,对list集合进行初始化
      public void startDocument() throws SAXException {
           list = new ArrayList<Student>();
     }
  2.startElement (String uri, String localName, String qName , Attributes attributes ):开始标签执行函数,qName为标签的名称,attributes为对象属性。
      public void startElement(String uri, String localName, String qName , Attributes attributes ) throws SAXException {
           if ( qName.equals( "student")) {
//如果标签名为student则初始化对象。
               student = new Student();
               for ( int i = 0; i < attributes.getLength(); i++) {
//attributes.getLength()返回的是对象属性的个数。这份xml文档中只是在<student>标签中添加了代表学生对象的id属性。
                    //attributes 是属性
                    if (attributes.getQName(i ).equals("id" )) {
                         student.setId( attributes.getValue( i));
                   }
              }
          }
//把标签值赋给全局变量tag,使characters方法中可判断标签,读出不同标签的数据。
           tag = qName;
     }
  3. endElement(String uri, String localName, String qName):结束标签
     public void endElement(String uri, String localName, String qName) throws SAXException {
//如果此结束标签为student则说明一个对象已经读完,把封装好的对象加入到list集合中。
            if (qName.equals( "student")) {
                 list.add( student);
           }
     }
 4. characters( char[] ch, int start, int length):把读到的内容存放在字符数组中(包含了很多空格)
public void characters(char[] ch, int start, int length) throws SAXException {
//把字符数组转换为一个字符串
           String info = new String(ch,start,length);
//info.trim()方法是把字符串中空格全部清空,之后判断如果不为空则进行标签判断
            if (! "".equals(info.trim())) {
                 if ( tag.equals( "name")) {
                      student.setName(info);
                }
                 if ( tag.equals( "age")) {
                      student.setAge(Integer. parseInt(info));
                }
                 if ( tag.equals( "phonenum")) {
                      student.setPhonenum(info);
                }
           }
     }
  • Student类只需要定义好xml文件<student>标签中的子元素所对应的变量,然后封装好,复写toString()方法方便打印。


  • PULL解析:
  • 通过Pull的方式来解析XMl文件。原理与SAX解析方式大致相同,与SAX方式对比有一个比较大的优点就是过程可控性强,通过switch()语句在主程序中能方便控制解析过程。而SAX方式则把对xml的解析过程全部交由handler对象来做,因此可控性差了。
  • Pull解析代码: 
           XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//创建pull解析工厂  
           XmlPullParser parser = factory.newPullParser(); //创建pull解析对象  
           parser.setInput( new FileReader( "students.xml"));//设置文件输入对象
 //获取状态值:event它的值分为:END_DOCUMENT、START_DOCUMENT、START_TAG、END_TAG几种。与SAX解析中的四个方法相似,此处是通过循环判断event的值来做出相对应的操作
            int  event = parser.getEventType(); 
                List<Student> list = null;
                Student student = null;
            while(event != XmlPullParser. END_DOCUMENT){//如果状态值为pull解析器的指定文档结束常量值则停止读取文件
                 switch (event) {
                 case XmlPullParser. START_DOCUMENT:
                     list = new ArrayList<Student>();
                      break;
                 case XmlPullParser. START_TAG:
                      if( "student".equals(parser.getName())){
                           student = new Student();
                            int len = parser.getAttributeCount();//属性数量
                            for ( int i = 0; i < len; i++) {
                                student.setId(parser.getAttributeValue(i));
                           }
                     }
                      if ( "name".equals(parser.getName())) {
                          student.setName(parser.nextText()); //注意这里是nextText而不是getText
                     }
                      if ( "age".equals(parser.getName())) {
                          student.setAge(Integer. parseInt(parser.nextText()));
                     }
                      if ( "phonenum".equals(parser.getName())) {
                          student.setPhonenum(parser.nextText());
                     }
                      break;
                 case XmlPullParser. END_TAG:
                      if ( "student".equals(parser.getName())) {
                           list.add(student);
                     }
                      break;
                 default:
                      break;
                }
                event = parser.next(); //读完一个标签再往下读,然后再去做判断是否读到结束标志。
           }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值