Java用SAX解析XML

摘要:
要解析的XML文件:myClass xml12<class>3<stuid=“001”>4<name>Allen</name>5<sex>male</index>6<age>20</age>7</su>8<stuid>“002”>9<name>namy</name<10<sex<female</index>11<age>18</age<12</su<13<stuid=“003”>14<name>lufy</name˃15<sex˃male</index.>16<age>18˂/age>17˂/su>18();55}5657//确定正在解析的元素是否具有属性值。如果是这样的话,将它们全部取出并保存到map对象中,例如:58if(attributes!

要解析的XML文件:myClass.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <class>
 3 <stu id="001">
 4 <name>Allen</name>
 5 <sex>男</sex>
 6 <age>20</age>
 7 </stu>
 8 <stu id="002">
 9 <name>namy</name>
10 <sex>女</sex>
11 <age>18</age>
12 </stu>
13 <stu id="003">
14 <name>lufy</name>
15 <sex>男</sex>
16 <age>18</age>
17 </stu>
18 </class>

用SAX解析XML的Handler类:Myhandler.java

  1 /**
  2  * 用SAX解析XML的Handler
  3  */
  4 package com.xml.util;
  5 
  6 import java.util.ArrayList;
  7 import java.util.HashMap;
  8 import java.util.List;
  9 import java.util.Map;
 10 
 11 import org.xml.sax.Attributes;
 12 import org.xml.sax.SAXException;
 13 import org.xml.sax.helpers.DefaultHandler;
 14 
 15 public class Myhandler extends DefaultHandler {
 16     //存储正在解析的元素的数据
 17     private Map<String,String> map=null;
 18     //存储所有解析的元素的数据
 19     private List<Map<String,String>> list=null;
 20     //正在解析的元素的名字
 21     String currentTag=null;
 22     //正在解析的元素的元素值
 23     String currentValue=null;
 24     //开始解析的元素
 25     String nodeName=null;
 26     
 27 
 28     public Myhandler(String nodeName) {
 29         // TODO Auto-generated constructor stub
 30         this.nodeName=nodeName;
 31     }
 32     
 33     public List<Map<String, String>> getList() {
 34         return list;
 35     }
 36 
 37     //开始解析文档,即开始解析XML根元素时调用该方法
 38     @Override
 39     public void startDocument() throws SAXException {
 40         // TODO Auto-generated method stub
 41         System.out.println("--startDocument()--");
 42         //初始化Map
 43         list=new ArrayList<Map<String,String>>();
 44     }
 45     
 46     //开始解析每个元素时都会调用该方法
 47     @Override
 48     public void startElement(String uri, String localName, String qName,
 49             Attributes attributes) throws SAXException {
 50         // TODO Auto-generated method stub
 51         //判断正在解析的元素是不是开始解析的元素
 52         System.out.println("--startElement()--"+qName);
 53         if(qName.equals(nodeName)){
 54             map=new HashMap<String, String>();
 55         }
 56         
 57         //判断正在解析的元素是否有属性值,如果有则将其全部取出并保存到map对象中,如:<person id="00001"></person>
 58         if(attributes!=null&&map!=null){
 59             for(int i=0;i<attributes.getLength();i++){
 60                 map.put(attributes.getQName(i), attributes.getValue(i));
 61             }
 62         }
 63         currentTag=qName;  //正在解析的元素
 64     }
 65     
 66     //解析到每个元素的内容时会调用此方法
 67     @Override
 68     public void characters(char[] ch, int start, int length)
 69             throws SAXException {
 70         // TODO Auto-generated method stub
 71         System.out.println("--characters()--");
 72         if(currentTag!=null&&map!=null){
 73             currentValue=new String(ch,start,length);
 74             //如果内容不为空和空格,也不是换行符则将该元素名和值和存入map中
 75             if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){
 76                 map.put(currentTag, currentValue);
 77                 System.out.println("-----"+currentTag+" "+currentValue);
 78             }
 79             //当前的元素已解析过,将其置空用于下一个元素的解析
 80             currentTag=null;
 81             currentValue=null;
 82         }
 83     }
 84     
 85     //每个元素结束的时候都会调用该方法
 86     @Override
 87     public void endElement(String uri, String localName, String qName)
 88             throws SAXException {
 89         // TODO Auto-generated method stub
 90         System.out.println("--endElement()--"+qName);
 91         //判断是否为一个节点结束的元素标签
 92         if(qName.equals(nodeName)){
 93             list.add(map);
 94             map=null;
 95         }
 96     }
 97     
 98     //结束解析文档,即解析根元素结束标签时调用该方法
 99     @Override
100     public void endDocument() throws SAXException {
101         // TODO Auto-generated method stub
102         System.out.println("--endDocument()--");
103         super.endDocument();
104     }
105 }

用于解析XML的业务类:SaxService.java

 1 /**
 2  * 封装解析业务类
 3  */
 4 package com.xml.service;
 5 
 6 import java.io.InputStream;
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 import javax.xml.parsers.SAXParser;
11 import javax.xml.parsers.SAXParserFactory;
12 
13 import com.xml.util.Myhandler;
14 
15 public class SaxService {
16     
17     public static List<Map<String,String>> ReadXML(String uri,String NodeName){
18         try {
19             //创建一个解析XML的工厂对象
20             SAXParserFactory parserFactory=SAXParserFactory.newInstance();
21             //创建一个解析XML的对象
22             SAXParser parser=parserFactory.newSAXParser();
23             //创建一个解析助手类
24             Myhandler myhandler=new Myhandler("stu");
25             parser.parse(uri, myhandler);
26             return myhandler.getList();
27         } catch (Exception e) {
28             e.printStackTrace();
29         }finally{
30             
31         }
32         return null;
33         
34     }
35 }
主程序入口:XmlSaxTest
 1 /**
 2  * 程序入口
 3  */
 4 package com.xml.sax;
 5 
 6 import java.util.ArrayList;
 7 import java.util.HashMap;
 8 import java.util.Iterator;
 9 import java.util.List;
10 import java.util.Map;
11 
12 import com.xml.service.SaxService;
13 
14 public class XmlSaxTest {
15 
16     /**
17      * @param args
18      */
19     public static void main(String[] args) {
20         // TODO Auto-generated method stub
21         ArrayList<Map<String, String>> list=(ArrayList<Map<String, String>>) SaxService.ReadXML("M:\\XML\\Demo\\myClass.xml","class");
22         /*for(int i=0;i<list.size();i++){
23             HashMap<String, String> temp=(HashMap<String, String>) list.get(i);
24                 Iterator<String> iterator=temp.keySet().iterator();
25                 while(iterator.hasNext()){
26                     String key=iterator.next().toString();
27                     String value=temp.get(key);
28                     System.out.print(key+" "+value+"--");
29                 }
30         }*/
31         System.out.println(list.toString());
32     }
33 
34 }
执行结果:
 1 --startDocument()--
 2 --startElement()--class
 3 --characters()--
 4 --startElement()--stu
 5 --characters()--
 6 --startElement()--name
 7 --characters()--
 8 -----name Allen
 9 --endElement()--name
10 --characters()--
11 --startElement()--sex
12 --characters()--
13 -----sex 男
14 --endElement()--sex
15 --characters()--
16 --startElement()--age
17 --characters()--
18 -----age 20
19 --endElement()--age
20 --characters()--
21 --endElement()--stu
22 --characters()--
23 --startElement()--stu
24 --characters()--
25 --startElement()--name
26 --characters()--
27 -----name namy
28 --endElement()--name
29 --characters()--
30 --startElement()--sex
31 --characters()--
32 -----sex 女
33 --endElement()--sex
34 --characters()--
35 --startElement()--age
36 --characters()--
37 -----age 18
38 --endElement()--age
39 --characters()--
40 --endElement()--stu
41 --characters()--
42 --startElement()--stu
43 --characters()--
44 --startElement()--name
45 --characters()--
46 -----name lufy
47 --endElement()--name
48 --characters()--
49 --startElement()--sex
50 --characters()--
51 -----sex 男
52 --endElement()--sex
53 --characters()--
54 --startElement()--age
55 --characters()--
56 -----age 18
57 --endElement()--age
58 --characters()--
59 --endElement()--stu
60 --characters()--
61 --endElement()--class
62 --endDocument()--
63 [{id=001, sex=男, age=20, name=Allen}, {id=002, sex=女, age=18, name=namy}, {id=003, sex=男, age=18, name=lufy}]
分析:用SAX解析XML采用的是从上而下的基于事件驱动的解析方式,在解析过程中会视情况自动调用startDocument()、startElement()、characters()、endElement()、endDocument()等相关的方法。
 
      由编译执行的结果来看:
  • startDocument()方法只会在文档开始解析的时候被调用,每次解析只会调用一次
  • startElement()方法每次在开始解析一个元素,即遇到元素标签开始的时候都会调用
  • characters()方法也是在每次解析到元素标签携带的内容时都会调用,即使该元素标签的内容为空或换行。而且如果元素内嵌套元素,在父元素结束标签前, characters()方法会再次被调用,此处需要注意。
  • endElement()方法每次在结束解析一个元素,即遇到元素标签结束的时候都会调用。
  • endDocument() startDocument()方法只会在文档解析结束的时候被调用,每次解析只会调用一次

免责声明:文章转载自《Java用SAX解析XML》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Winform开发常用控件之DataGridView的简单数据绑定——自动绑定Diameter 消息格式解析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SpringBoot+ElementUI实现通用文件下载请求(全流程图文详细教程)

场景 在某些场景下需要前端浏览器从服务器端下载文件,比如需要下载导入Excel的模板。 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。 实现 既然是实现通用下载接口,就要实现在后端配置一个下载文件的路径,在前端进行下载请求时传递要下载的文件...

Kotlin入门(14)继承的那些事儿

上一篇文章介绍了类对成员的声明方式与使用过程,从而初步了解了类的成员及其运用。不过早在《Kotlin入门(12)类的概貌与构造》中,提到MainActivity继承自AppCompatActivity,而Kotlin对于类继承的写法是“class MainActivity : AppCompatActivity() {}”,这跟Java对比有明显差异,那么...

Java | Optional的12种实践建议

本篇翻译Mohamed Taman的Optional12种实践建议 Recipe 1: 不要给optional 变量赋null值 有时候,当开发人员在处理数据库以查询一个employee时,会设计一个方法来返回Optional;如果没有结果返回从数据库,有一些开发人员仍然返回null,,例如: 1 public Optional<Employee&g...

缓存子系统如何设计

缓存子系统如何设计 大家对这段代码肯定很熟悉吧: public List<UserInfo> SearchUsers(stringuserName) { string cacheKey=string.Format("SearchUsers_{0}", userName);...

Asp.net mvc与PHP的Session共享的实现

最近在做的一个ASP.NET MVC的项目,要用到第三方的php系统,为了实现两个系统的互联互通。决定将两者的session打通共享。让asp.net mvc 和php 都能正常访问和修改Session内容。 在决定实现之前,先搜索了一下院子里有没有相类似的文章,对于跨语言的程序互通,有两种方案: (1) SSO单点登录,其实就是把用户名和密码传给另一个系...

Java 的ArrayList构造方法

目录 ArrayList 构造方法使用 ArrayList 类常用方法 ArrayList集合存储字符串遍历 简单的学生管理系统   1、ArrayList 构造方法 ArrayList类概述  什么是集合   提供一种存储空间可变的存储模型,存储的数据容量可以发生改变 ‘   ArrayList集合的特点 底层是数组实现的,长度可以变化   泛型的...