• 笔记:XML-解析文档-流机制解析器(SAX、StAX)


    DOM 解析器完整的读入XML文档,然后将其转换成一个树型的数据结构,对于大多数应用,DOM 都运行很好,但是,如果文档很大,并且处理算法又非常简单,可以在运行时解析节点,而不必看到完整的树形结构,那么我们应该使用流机制解析器(streaming parser),Java 类库提供的流解析机制有 SAX 解析器和 StAX 解析器,SAX 解析器是基于事件回调机制,而 StAX解析器提供了解析事件的迭代器。

    1. 使用SAX解析器

      SAX 解析器在解析XML 输入的组成部分时会报告事件,在使用 SAX 解析器时,需要一个处理器来为不同的解析器事件定义事件动作,ContentHandler 接口定义了若干个在解析文档时解析器会调用的回调方法,我们可以使用 DefaultHandler 类,该类继承与 ContentHandler 并提供了默认实现,重要的方法如下:

    • startDocument:在文档开始时调用一次
    • endDocument:在文档结束时调用一次
    • startElement:在遇到起始标签时调用,有3个描述元素名的参数,其中qName参数标识标签限定名,如果命名空间处理特性打开,则 uri 表示的是命名空间,localName 表示的是本地名。
    • endElement:在遇到结束标签时调用,其参数和 startElement 一致
    • characters:在每当遇到字符数据时调用,如果标签没有内容,但有子标签时,其中的空格会作为字符数据返回

    示例代码如下:

    • 事件处理类

      public class CustomDefaultHandler extends DefaultHandler {

              @Override

              public void startDocument() throws SAXException {

                      super.startDocument();

         

                      System.out.println("call startDocument");

              }

         

              @Override

              public void endDocument() throws SAXException {

                      super.endDocument();

                      System.out.println("call endDocument");

              }

         

              @Override

              public void characters(char[] ch, int start, int length) throws SAXException {

                      super.characters(ch, start, length);

         

                      String chs = new String(ch, start, length);

                      System.out.println("characters ch=" + chs + " start=" + start + " length=" + length);

              }

         

              @Override

              public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

                      super.startElement(uri, localName, qName, attributes);

         

                      StringBuilder sb = new StringBuilder();

                      for (int i = 0; i < attributes.getLength(); i++) {

                              sb.append(attributes.getLocalName(i) + "="" + attributes.getValue(i) + "" ");

                      }

         

                      System.out.println("startElement qName=" + qName + " Uri=" + uri + " localName=" + localName + " "

      + sb.toString());

              }

         

              @Override

              public void endElement(String uri, String localName, String qName) throws SAXException {

                      super.endElement(uri, localName, qName);

         

                      System.out.println("endElement " + qName);

              }

      }

    • 调用类

      try {

              Path xmlPath = Paths.get("E:\IDEA Workspace\exampleiostream\src\main\java\org\drsoft\examples\xml", "appParse.xml");

              InputStream xmlStream = Files.newInputStream(xmlPath, StandardOpenOption.READ);

              SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();

              SAXParser saxParser = saxParserFactory.newSAXParser();

              saxParser.parse(xmlStream, new CustomDefaultHandler());

      } catch (SAXException e) {

                e.printStackTrace();

      } catch (ParserConfigurationException e) {

                e.printStackTrace();

      } catch (IOException e) {

                e.printStackTrace();

      }

    1. 使用StAX解析器

      StAX 解析器时一种拉解析器(pull parser),与安装事件处理器不同,只需要使用基本的循环来迭代所有事件,示例代码如下:

      try {

            Path xmlPath = Paths.get("E:\IDEA Workspace\exampleiostream\src\main\java\org\drsoft\examples\xml", "appParse.xml");

            InputStream xmlStream = Files.newInputStream(xmlPath, StandardOpenOption.READ);

         

            XMLInputFactory factory = XMLInputFactory.newFactory();

            XMLStreamReader parser = factory.createXMLStreamReader(xmlStream);

         

            while (parser.hasNext()) {

                        int event = parser.next();

                        switch (event) {

                                case XMLStreamConstants.START_DOCUMENT:

                                          System.out.println("START_DOCUMENT Call");

                                          break;

         

                                case XMLStreamConstants.END_DOCUMENT:

                                          System.out.println("END_DOCUMENT Call");

                                          break;

         

                                case XMLStreamConstants.START_ELEMENT:

                                          StringBuilder sb = new StringBuilder();

                                          for (int i = 0; i < parser.getAttributeCount(); i++) {

                                                  sb.append(parser.getAttributeName(i) + "="" + parser.getAttributeValue(i) + "" ");

                                          }

                                          System.out.println("START_ELEMENT qName=" + parser.getName() + " Uri="

      + parser.getNamespaceURI() + " localName=" + parser.getLocalName() + " attribute="

      + sb.toString());

                                          break;

         

                                case XMLStreamConstants.END_ELEMENT:

                                          System.out.println("END_ELEMENT qName=" + parser.getName() + " Uri=" + parser.getNamespaceURI()

                                                           + " localName=" + parser.getLocalName());

                                          break;

         

                                case XMLStreamConstants.CHARACTERS:

                                          int start = parser.getTextStart();

                                          int length = parser.getTextLength();

                                          System.out.println("CHARACTERS text=" + new String(parser.getTextCharacters(), start, length));

                                          break;

                      }

            }

      } catch (IOException e) {

              e.printStackTrace();

      } catch (XMLStreamException e) {

            e.printStackTrace();

      }

         

         

  • 相关阅读:
    【解题报告】洛谷P1038 神经网络
    【解题报告】洛谷P6475 建设城市
    【解题报告】洛谷P4138 挂饰
    【解题报告】洛谷P3870 开关
    【解题报告】洛谷P1120 小木棍
    洛谷P1168 中位数
    FWT(快速沃尔什变换)
    lucas和扩展lucas
    exBSGS
    2_sat
  • 原文地址:https://www.cnblogs.com/li3807/p/6876124.html
Copyright © 2020-2023  润新知