A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© zzj123 黑马粉丝团   /  2017-6-13 11:30  /  1104 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

SAX概述

1 SAX解析原理
首先我们想一下,DOM解析器是不是需要把XML文档遍历一次,然后把每次读取到的数据转换成节点对象(到底哪一种节点对象,这要看解析时遇到了什么东西)保存起来,最后生成一个Document对象返回。也就是说,当你调用了builder.parse(“a.xml”)后,这个方法就会把XML文档中的数据转换成节点对象保存起来,然后生成一个Document对象。这个解析XML文档的过程在parse()方法调用结束后也就结束了。我们的工作是在解析之后,开始对Document对象进行操作。
但是SAX不同,当SAX解析器的parse()方法调用结束后,不会给我们一个Document对象,而是什么都不给。SAX不会把XML数据保存到内存中,如果我们的解析工作是在SAX解析器的parse()方法调用结束后开始,那么就已经晚了!!!这说明我们必须在SAX解析XML文档的同时完成我们的工作。
SAX解析器在解析XML文档的过程中,读取到XML文档的一个部分后,会调用ContentHandler(内部处理器)中的方法。例如当SAX解析到一个元素的开始标签时,它会调用ContentHandler的startElement()方法;在解析到一个元素的结束标签时会调用ContentHandler的endElement()方法。
ContentHandler是一个接口,我们的工作是编写该接口的实现类,然后创建实现类的对象,在SAX解析器开始解析之前,把我们写的内容处理类对象交给SAX解析器,这样在解析过程中,我们的内容处理中的方法就会被调用了。

2 获取SAX解析器
与DOM相同,你应该通过JAXP获取SAX解析器,而不是直接使用特定厂商的SAX解析器。JAXP查找特定厂商的SAX解析器实现的方式与查找DOM解析器实现的方式完全相同,这里就不在赘述了。
                SAXParserFactory factory = SAXParserFactory.newInstance();
                javax.xml.parsers.SAXParser parser = factory.newSAXParser();
                parser.parse("src/students.xml", new MyContentHandler());

  上面代码中,MyContentHandler就是我们自己需要编写的ContentHandler的实现类对象。

3 内容处理器
org.xml.sax.ContentHandler中的方法:
void setDocumentLocator(Locator locator):与定位相关,例如获取行数、实体、标识等信息,我们可以忽略他的存在;
void startDocument() throws SAXException:文档开始解析之前被调用;
void endDocument() throws SAXException:文档解析结束之后被调用;
void startPrefixMapping(String prefix,String uri)throws SAXException:与名称空间相关,忽略;
void endPrefixMapping(String prefix) throws SAXException:与名称空间相关,忽略;
void startElement(String uri,String local,String qName,Attributes atts)throws SAXException:开始解析一个元素时被调用,其中uri、local这两个参数与名称空间相关,可以忽略。qName表示当前元素的名称,atts表示当前元素的属性集合;
void endElement(String uri,String localName,String qName)throws SAXException:一个元素解析结束后会被调用;
void characters(char[] ch,int start,int length)throws SAXException:解析到文本数据时会被调用,ch表示当前XML文档所有内容对应的字符数组,不只是当前文本元素的内容。start表示当前文本数据在整个XML文档中的开始下载位置,length是当前文本数据的长度;
void ignorableWhitespace(char[] ch,int start,int length)throws SAXException:解析到空白文本数据时会被调用,可以忽略!
void processingInstruction(String target,String data)throws SAXException:解析到处理指令时会被调用,可以忽略!
void skippedEntity(String name)throws SAXException:解析到实体时会被调用,可以忽略!

  org.xml.sax.helpers.DefualtHandler对ContentHandler做了空实现,所以我们可以自定义内容处理器时可以继承DefaultHandler类。
SAX应用

1测试SAX
public class SAXTest {
        @Test
        public void testSAX() throws ParserConfigurationException, SAXException, IOException {
                SAXParserFactory factory = SAXParserFactory.newInstance()[获取解析器工厂];
                SAXParser parser = factory.newSAXParser();[创建解析器对象]
                parser.parse("src/students.xml", new MyContentHandler())[开始解析students.xml文档];
        }
        private static class MyContentHandler [内容处理器类]extends DefaultHandler {
                @Override
                public void startDocument[当XML文档开始解析时该方法被调用]() throws SAXException {
                        System.out.println("开始解析...");
                }
                @Override
                public void endDocument[当XML文档解析结束时该方法被调用]() throws SAXException {
                        System.out.println("解析结束...");
                }
                @Override
                public void startElement[当开始解析一个元素时,该方法被调用](String uri, String localName, String qName,
                                Attributes atts) throws SAXException {
                        System.out.println(qName + "元素解析开始");
                }
                @Override
                public void endElement[当解析一个元素结束时,该方法被调用](String uri, String localName, String qName)
                                throws SAXException {
                        System.out.println(qName + "元素解析结束");
                }
                @Override
                public void characters[当解析到文本内容时,该方法被调用](char[] ch, int start, int length)
                                throws SAXException {
                        String s = new String(ch, start, length);
                        if(s.trim().isEmpty()) {
                                return;
                        }
                        System.out.println("文本内容:" + s);
                }
                @Override
                public void ignorableWhitespace[当解析到空白文本内容时,该方法被调用](char[] ch, int start, int length)
                                throws SAXException {
                       
                }
                @Override
                public void processingInstruction(String target, String data)
                                throws SAXException {
                        System.out.println("处理指令");
                }
        }
}

2 使用SAX打印XML文档
public class SAXTest2 {
        @Test
        public void testSAX() throws
ParserConfigurationException, SAXException, IOException {
                SAXParserFactory factory = SAXParserFactory.newInstance();
                SAXParser parser = factory.newSAXParser();
                parser.parse("src/students.xml", new MyContentHandler());
        }
        private static class MyContentHandler extends DefaultHandler {
                @Override
                public void startDocument() throws SAXException {
                        System.out.println("<?xml version='1.0' encoding='utf-8'?>");
                }

                @Override
                public void startElement(String uri, String localName, String qName,
                                Attributes atts) throws SAXException {
                        StringBuilder sb = new StringBuilder();
                        sb.append("<").append(qName);
                        for(int i = 0; i < atts.getLength(); i++) {
                                sb.append(" ");
                                sb.append(atts.getQName(i));
                                sb.append("=");
                                sb.append("'");
                                sb.append(atts.getValue(i));
                                sb.append("'");
                        }
                        sb.append(">");
                        System.out.print(sb);
                }

                @Override
                public void endElement(String uri, String localName, String qName)
                                throws SAXException {
                        System.out.print("</" + qName + ">");
                }

                @Override
                public void characters(char[] ch, int start, int length)
                                throws SAXException {
                        System.out.print(new String(ch, start, length));
                }
        }
}
您需要登录后才可以回帖 登录 | 加入黑马