XML编程总结(三)——使用SAX接口操作xml

(三)使用SAX接口操作xml

SAX解析器被称为SAXParser,SAXParser是由javax.xml.parsers.SAXParserFactory创建的。与DOM解析器不同,SAX解析器并不创建XML文档的内存表示,因此会占用更少的内存。SAX解析器通过调用回调方法(事件驱动)将XML文档结构通知客户端,也就是通过调用提供给SAXParser的org.xml.sax.helpers.DefaultHandler处理器内的方法。

org.xml.sax.helpers.DefaultHandler类实现了ContentHandler、ErrorHandler、DTDHandler以及EntityResolver等接口。其中,回调方法是通过事件驱动来调用。最重要的方法有:

startDocument()和endDocument()方法,遇到XML文档的开始和结束时被调用;

startElement()和endElement()方法,遇到一个文档元素的开始和结束时被调用;

characters()方法,遇到元素的开始标签和结束标签之间的文本数据时被调用。

因此,程序员只需继承org.xml.sax.helpers.DefaultHandler该类,并实现该类的回调方法即可。

测试类代码:

 1 public class SAXTest {
 2     @Test
 3     public void testRetrieve() throws Exception{
 4         //创建SAXParser的工厂
 5         SAXParserFactory factory=SAXParserFactory.newInstance();
 6         //创建SAXParser解析器对象
 7         SAXParser parser = factory.newSAXParser();
 8         //获得xml文档的输入流
 9         InputStream is=SAXTest.class.getClassLoader().getResourceAsStream("books.xml");
10         //利用Handler对文档进行解析
11         parser.parse(is, new TechDefaultHandler());
12         //获得文档的读对象
13         XMLReader reader = parser.getXMLReader();        
14     }
15 }

DefaultHandler的子类代码:

 1 public class TechDefaultHandler extends DefaultHandler {
 2     // 使用栈这个数据结构来保存
 3     private Stack<String> stack = new Stack<String>();
 4 
 5     // 数据
 6     private String title;
 7     private String author;
 8     private String year;
 9     private double price;
10     
11     /**
12      * 遇到文档开始元素时调用
13      */
14     @Override
15     public void startDocument() throws SAXException {
16         System.out.println("startDocument");
17         
18     }
19 
20     /**
21      * 遇到文档结束元素时调用
22      */
23     @Override
24     public void endDocument() throws SAXException {
25         System.out.println("endDocument");
26     }
27 
28     /**
29      * 遇到元素开始元素时调用
30      * 获取属性为web的book元素的price元素文本
31      */
32     @Override
33     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
34         // 将标签名压入栈
35         stack.push(qName);
36 
37         // 处理属性
38         for (int i = 0; i < attributes.getLength(); ++i)
39         {
40             String attrName = attributes.getQName(i);
41             String attrValue = attributes.getValue(i);
42 
43             System.out.println("属性: " + attrName + "=" + attrValue);
44 
45         }
46         
47     }
48 
49     /**
50      * 遇到元素结束元素时调用
51      */
52     @Override
53     public void endElement(String uri, String localName, String qName) throws SAXException {
54         stack.pop();// 表示该元素解析完毕,需要从栈中弹出标签
55 
56         if ("book".equals(qName)) {
57             System.out.println("Book info: -------");
58             System.out.println("    title: " + title);
59             System.out.println("    author: " + author);
60             System.out.println("    year: " + year);
61             System.out.println("    price: " + price);
62             System.out.println();
63         }
64     }
65 
66     /**
67      * 遇到文档节点时调用
68      */
69     @Override
70     public void characters(char[] ch, int start, int length) throws SAXException {
71         // 取出标签名
72         String tag = stack.peek();
73 
74         if ("title".equals(tag))
75         {
76             title = new String(ch, start, length);
77 
78         }
79         else if ("author".equals(tag))
80         {
81             author = new String(ch, start, length);
82         }
83         else if ("year".equals(tag))
84         {
85             year = new String(ch, start, length);
86         }
87         else if ("price".equals(tag))
88         {
89             price = Double.parseDouble(new String(ch, start, length));
90         }
91         
92     }
93 
94     @Override
95     public void error(SAXParseException e) throws SAXException {
96         System.out.println(e.getMessage());
97     }
98 
99 }

 

posted @ 2016-10-15 19:13  悟道&匠心  阅读(833)  评论(0编辑  收藏  举报