小兔网

在上篇文章中,简单介绍了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--;          }      }  }

以上是RootElement类得源码,从源码可以看出,它只是将defaultHandler简单的处理一下。


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

/**       * 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() {                            @Override              public 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() {                            @Override              public 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;                    }

 android sax解析xml文件(二)

我们都知道通过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文件(二)的内容,更多相关内容请关注小兔网(www.zhishitu.com)!