在上篇文章中,简单介绍了sax解析xml的一种方式,它是继承defaultHandler方式,并重写其中的几个方法来实现的。

接下来说的第二种方式是用RootElement这个类来解析的,RootElement 内置了defaultHandler的子类,

RootElement 源码如下:


public class RootElement extends Element {    final Handler handler = new Handler();    /**     * Constructs a new root element with the given name.     *     * @param uri the namespace     * @param localName the local name     */    public RootElement(String uri, String localName) {        super(null, uri, localName, 0);    }    /**     * Constructs a new root element with the given name. Uses an empty string     * as the namespace.     *     * @param localName the local name     */    public RootElement(String localName) {        this("", localName);    }    /**     * Gets the SAX {@code ContentHandler}. Pass this to your SAX parser.     */    public ContentHandler getContentHandler() {        return this.handler;    }    class Handler extends DefaultHandler {        Locator locator;        int depth = -1;        Element current = null;        StringBuilder bodyBuilder = null;        @Override        public void setDocumentLocator(Locator locator) {            this.locator = locator;        }        @Override        public void startElement(String uri, String localName, String qName,                Attributes attributes) throws SAXException {            int depth = ++this.depth;            if (depth == 0) {                // This is the root element.                startRoot(uri, localName, attributes);                return;            }            // Prohibit mixed text and elements.            if (bodyBuilder != null) {                throw new BadXmlException("Encountered mixed content"                        + " within text element named " + current + ".",                        locator);            }            // If we're one level below the current element.            if (depth == current.depth + 1) {                // Look for a child to push onto the stack.                Children children = current.children;                if (children != null) {                    Element child = children.get(uri, localName);                    if (child != null) {                        start(child, attributes);                    }                }            }        }        void startRoot(String uri, String localName, Attributes attributes)                throws SAXException {            Element root = RootElement.this;            if (root.uri.compareTo(uri) != 0                    || root.localName.compareTo(localName) != 0) {                throw new BadXmlException("Root element name does"                        + " not match. Expected: " + root + ", Got: "                        + Element.toString(uri, localName), locator);            }            start(root, attributes);        }        void start(Element e, Attributes attributes) {            // Push element onto the stack.            this.current = e;            if (e.startElementListener != null) {                e.startElementListener.start(attributes);            }            if (e.endTextElementListener != null) {                this.bodyBuilder = new StringBuilder();            }                        e.resetRequiredChildren();            e.visited = true;        }        @Override        public void characters(char[] buffer, int start, int length)                throws SAXException {            if (bodyBuilder != null) {                bodyBuilder.append(buffer, start, length);            }        }        @Override        public void endElement(String uri, String localName, String qName)                throws SAXException {            Element current = this.current;            // If we've ended the current element...            if (depth == current.depth) {                current.checkRequiredChildren(locator);                // Invoke end element listener.                if (current.endElementListener != null) {                    current.endElementListener.end();                }                // Invoke end text element listener.                if (bodyBuilder != null) {                    String body = bodyBuilder.toString();                    bodyBuilder = null;                    // We can assume that this listener is present.                    current.endTextElementListener.end(body);                }                // Pop element off the stack.                this.current = current.parent;            }            depth--;        }    }}


具体应用可以参照我写的测试源码


/** * sax解析xml的第二种方式 * 用XMLReader 也是sax的一种方式 * @return */private String saxParseSecond(){//读取src下xml文件InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("saxTest.xml");SAXParserFactory factory = SAXParserFactory.newInstance();try {SAXParser parse = factory.newSAXParser();XMLReader reader = parse.getXMLReader();reader.setContentHandler(getRootElement().getContentHandler());reader.parse(new InputSource(inputStream));} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}


/**      *       * @return 返回设置好处理机制的rootElement      */      private RootElement getRootElement(){                    /*rootElement代表着根节点,参数为根节点的tagName*/          RootElement rootElement = new RootElement("classes");          /*获取一类子节点,并为其设置相应的事件          * 这里需要注意,虽然我们只设置了一次group的事件,但是我们文档中根节点下的所有          * group却都可以触发这个事件。          * */          Element groupElement = rootElement.getChild("group");          // 读到元素开始位置时触发,如读到<group>时          groupElement.setStartElementListener(new StartElementListener() {              @Override              public void start(Attributes attributes) {  //                Log.i("TEST", "start");                 String groupName =  attributes.getValue("name");               String groupNum =  attributes.getValue("num");               result = result+"groupName ="+groupName+"groupNum = "+groupNum+"\n";            }          });          //读到元素结束位置时触发,如读到</group>时          groupElement.setEndElementListener(new EndElementListener() {              @Override              public void end() {              }          });          Element personElement = groupElement.getChild("person");        //读取<person>标签触发        personElement.setStartElementListener(new StartElementListener() {@Overridepublic void start(Attributes attributes) { String personName =  attributes.getValue("name");             String age =  attributes.getValue("age");             result = result+"personName ="+personName+"age = "+age+"\n";}});        //读取</person>标签触发        personElement.setEndElementListener(new EndElementListener() {@Overridepublic void end() {}});                Element chinese = personElement.getChild("chinese");  //        chinese.setTextElementListener(new TextElementListener() {////@Override//public void end(String body) {//// TODO Auto-generated method stub////}////@Override//public void start(Attributes attributes) {//// TODO Auto-generated method stub////}//});        // 读到文本的末尾时触发,这里的body即为文本的内容部分          chinese.setEndTextElementListener(new EndTextElementListener() {              @Override              public void end(String body) {              Pattern p = Pattern.compile("\\s*|\t|\r|\n"); Matcher m = p.matcher(body); body = m.replaceAll("");             result = result+"chinese ="+body;            }          });                    Element english = personElement.getChild("english");          english.setEndTextElementListener(new EndTextElementListener() {              @Override              public void end(String body) {              Pattern p = Pattern.compile("\\s*|\t|\r|\n"); Matcher m = p.matcher(body); body = m.replaceAll("");                result = result+"english ="+body+"\n";            }          });          return rootElement;                }



我们都知道通过SAXParser对象解析xml的方式,这里我们又从代码中看到了利用另一个对象XMLReader进行解析,那么两者到底有什么联系和区别呢?

其实SAXParser是在SAX 1.0 定义的,而XMLReader则是在2.0中才开始出现的。你可以认为XMLReader的出现是为了替代SAXParser解析的,两者本质上干的事情是一样的,只不过XMLReader的功能更加的强悍而已。

关于XMLReader的获取方式,除了通过SAXParser的getXMLReader方法获得之外,我们还可以通过以下两种方式。

XMLReader parser=XMLReaderFactory.createXMLReader(); (1)XMLReader parser=XMLReaderFactory.createXMLReader(String className); (2)


以上就是android sax解析xml文件(二)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

更多相关文章

  1. android sax解析 xml方式
  2. android pull 解析xml方式
  3. Java&Xml教程(三)使用DOM方式修改XML文件内容
  4. Java&Xml教程(二)使用DOM方式解析XML文件
  5. Java&Xml教程(四)使用DOM方式生成XML文件
  6. Java&Xml教程(五)使用SAX方式解析XML文件
  7. xml学习(7) .net 获取xml节点或者属性最大值
  8. 效率最高的xml解析方式
  9. FireFox对XML的处理兼容IE的节点处理方法

随机推荐

  1. asasasa
  2. Android: Android Reboot流程
  3. android中的tab小结
  4. asss
  5. android安装SDK时遇到的一些问题
  6. Android图表 - Charts for Android
  7. Androidの游戏源码下载地址
  8. android 中theme.xml与style.xml的区别
  9. Android Wear - Design Principles for A
  10. [Android] 环境配置之基础开发环境(SDK/An