笔记: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();

    }

    ?
    ?

    ?
    ?

时间: 2024-12-29 17:06:33

笔记:XML-解析文档-流机制解析器(SAX、StAX)的相关文章

文档流的解析

<!-- 文档流1,跨级元素独占一行,几个块级元素就独占几行.2,行内元素会从左向右排满,折行继续排版.3,绝对定位(absolute) 固定定位(fixed) 会脱离文档流,不占位,前后元素会忽略它们. 根据指定位置进行排版,且任何元素进行以上两种定位都会变成块级元素,可以设置宽高.4,浮动元素,会脱离文档流,且一定会占位,后面如果是块级元素则会忽略它的存在, 围绕着它进行排版,另外浮动后的元素就变成块级元素,可以设置宽高, 包括行内元素,如行内元素没有设置,则按照原来宽高进行占位. -->

源生API解析XML文档与dom4j解析XML文档

一.XML语言 XML是一种可扩展的标记语言,是一种强类型的语言,类似HTML(超文本标记语言,是一种弱类型的语言).XML是一种通用的数据交换格式(关系型数据库),综上所诉:XML可以传输数据,也可以存储数据. 1.XML语言书写的注意事项 1.XML标签命名自定义[推荐英文],标签名中不能包含空格 2.XML空格和换行都表示数据,严格区分大小写 3.XML中特殊字符表示的数据需要使用特殊字符编码和HTML一样 4.CDATA区中的数据不会被识别为语法 <![CDATA[王天霸<>&l

XML之DOM解析文档

TestDom.java package com.sxt.dom; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Do

XML文档的DOM解析

xml的DOM解析: <?xml version="1.0" encoding="UTF-8"?> <books> <!--根节点--><!--这里的空白也算一个节点,所以books共有5个子节点--> <book id="book1" w="wwwww"> <name><a>AAAAAA</a>bookName1</name

使用JAXP对XML文档进行DOM解析

一.XML解析方式分为两种:dom和sax dom:(Document Object Model,即文档对象模型)是W3C组织推荐的解析XML的一种方式. sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有的XML解析器都支持它. dom和sax解析方法的区别: dom:对文档CRUD(增删改查)比较方便,缺点:占用内存比较大(将xml文件全部读入内存). sax:占用内存较少,解析速度快(从上往下读一行解析一行).缺点:只适合读取,不适合CRU

PHP解析XML格式文档

<?php// 首先要建一个DOMDocument对象$xml = new DOMDocument();// 加载Xml文件$xml->load("3.xml");// 获取所有的post标签$postDom = $xml->getElementsByTagName("PROPERTIES");print_r($postDom);echo '<br>';// 循环遍历post标签    foreach($postDom as $post

[Swift通天遁地]七、数据与安全-(2)使用Fuzi(斧子)类库实现对XML和HTML文档的快速解析

本文将演示使用Fuzi(斧子)类库实现对XML和HTML文档的快速解析. 首先确保在项目中已经安装了所需的第三方库. 点击[Podfile],查看安装配置文件. 1 platform :ios, '12.0' 2 use_frameworks! 3 4 target 'DemoApp' do 5 source 'https://github.com/CocoaPods/Specs.git' 6 pod 'Fuzi' 7 end 根据配置文件中的相关配置,安装第三方库. 然后点击打开[DemoAp

从文档流角度理解浏览器页面渲染引擎对元素定位的解析

文档流:将窗体自上而下分成一行一行,并在每行中按从左至右的挨次排放元素,即为文档流. 我们在排列元素时,遵循"流式结构",即元素遵循从上向下,从左向右堆叠的规则,所以我们在排列元素时如果每行从左往右的元素的总宽度大于窗口的宽度时,就会默认换行. 有三种状况将使得元素离开文档流而存在,分别是浮动.绝对定位.固定定位. 浮动时,离开文档流后的元素,不占用文档流的空间,不会被文档流中的元素发现,离开文档流元素后面的还在文档流上元素会自动上来填补位置接上文档流.此时,离开文档流的元素如同浮在文

DedeCMS模板文件不存在,无法解析文档! 问题定位方法

生成静态的时候,经常会遇到“模板文件不存在,无法解析文 档!”的问题.很多朋友试过论坛里很多方法,都是针对某些人可以解决,某些人的问题依旧,为什么呢?其实问题很可能确实是多种多样的,表现结果却是一样, 所以,问题的原因就不好找了.下面介绍一个方法方便定位错误的地方:s200.CN 直接去Include文件夹里搜索“模板文件不存在,无法解析文档”这串字符.找到以下五个文件: arc.archives.class.phparc.listview.class.phparc.sglistview.cla