XML文件解析方式之一是SAX方式,SAX解析方式会逐行地去扫描XML文档,当遇到标签时会触发解析处理器,采用事件处理的方式解析XML (Simple API for XML) 。SAX是一个用于处理XML事件驱动的“推”模型,虽然不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。

SAX解析不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。常见的事件处理器有三种基本类型:

  • 用于访问XML DTD内容的DTDHandler;
  • 用于低级访问解析错误的ErrorHandler;
  • 用于访问文档内容的ContentHandler,这也是最普遍使用的事件处理器。

解析器读取输入文档并在处理文档时将每个事件推给文档处理器(MyContentHandler)。

  与DOM相比,SAX解析器能提供更好的性能优势,它提供对XML文档内容的有效低级访问。SAX模型最大的优点是内存消耗小,因为整个文档无需一次加载到内存中,这使SAX解析器可以解析大于系统内存的文档。另外,你无需像在DOM中那样为所有节点创建对象。最后,SAX“推”模型可用于广播环境,能够同时注册多个ContentHandler,并行接收事件,而不是在一个管道中一个接一个地进行处理。

  SAX的缺点是必须实现多个事件处理程序以便能够处理所有到来的事件,同时你还必须在应用程序代码中维护这个事件状态,因为SAX解析器不能交流元信息,如DOM的父/子支持,所以你必须跟踪解析器处在文档层次的哪个位置。如此一来,你的文档越复杂,你的应用逻辑就越复杂。虽然没有必要一次将整个文档加载到内存中,但SAX解析器仍然需要解析整个文档,这点和DOM一样。也许SAX面临的最大问题是它没有内置如XPath所提供的那些导航支持。再加上它的单遍解析,使它不能支持随机访问。这一限制也表现在名字空间上: 对有继承名字空间的元素不做注解。这些限制使SAX很少被用于操作或修改文档。

  那些只需要单遍读取内容的应用程序可以从SAX解析中大大受益。很多B2B和EAI应用程序将XML用做封装格式,接收端用这种格式简单地接收所有数据。这就是SAX明显优于DOM的地方:因高效而获得高吞吐率。在SAX 2.0 中有一个内置的过滤机制,可以很轻松地输出一个文档子集或进行简单的文档转换。

一、SAX解析方式的步骤

SAX解析可分四个步骤进行:

  1. 得到xml文件对应的资源,可以是xml的输入流,文件或uri
  2. 得到SAX解析工厂(SAXParserFactory)
  3. 由解析工厂生产一个SAX解析器(SAXParser)
  4. 传入输入流和handler给解析器,调用parse()解析

二、SAX的常用接口介绍

1、ContentHandler接口

 该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束、元素开头和结束、以及元素中的字符数据等事件。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。ContentHandler接口的方法有以下几种:

  void startDocument()void endDocument()void startElement(String uri, String localName, String qName, Attributes atts)void endElement(String uri, String localName, String qName)void characters(char[ ] ch, int start, int length)

2、ErrorHandler接口

  ErrorHandler接口是SAX错误处理程序的基本接口。如果SAX应用程序需要实现自定义的错误处理,则它必须实现此接口,然后解析器将通过此接口报告所有的错误和警告。该接口的方法如下:

  void error(SAXParseException exception)void fatalError(SAXParseException exception)void warning(SAXParseException exception)

3、DTDHandler接口

DTDHandler用于接收基本的DTD相关事件的通知,仅包括DTD事件的注释和未解析的实体声明部分。SAX解析器可按任何顺序报告这些事件,而不管声明注释和未解析实体时所采用的顺序;但是,必须在文档处理程序的startDocument()事件之后,在第一个startElement()事件之前报告所有的DTD事件。DTDHandler接口包括以下两个方法:

  void startDocumevoid notationDecl(String name, String publicId, String systemId) nt()void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)

4、EntityResolver接口

EntityResolver接口是用于解析实体的基本接口,该接口只有一个方法,如下:

  public InputSource resolveEntity(String publicId, String systemId)

  解析器将在打开任何外部实体前调用此方法。此类实体包括在DTD内引用的外部DTD子集和外部参数实体和在文档元素内引用的外部通用实体等。如果SAX应用程序需要实现自定义处理外部实体,则必须实现此接口。

三、Xerces C++ SAX解析XML文档

1、编译xerces

https://blog.csdn.net/t18438605018/article/details/117478843

2、在工程中使用xerces

  1. 编译xerces成功后,在生成目录会生成xerces-c_3_1D.dll,xerces-c_3_1D.lib。(如果是release模式,就不会有后面的D)
  2. 新建VS工程,添加C++/include目录和link/xerces-c_3_1D.lib,拷贝xerces-c_3_1D.dll到工程生成目录
  3. 添加测试程序
// MySAXHandler.h
#pragma once
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>XERCES_CPP_NAMESPACE_USEclass MySAX2Handler : public DefaultHandler
{
public:MySAX2Handler();~MySAX2Handler();
public:void startElement(const   XMLCh* const    uri,const   XMLCh* const    localname,const   XMLCh* const    qname,const   Attributes&     attrs);void characters(const   XMLCh* const    chars,const XMLSize_t       length);void endElement(const XMLCh* const uri,const XMLCh* const localname,const XMLCh* const qname);void fatalError(const SAXParseException&);
};
// MySAXHandler.cpp#include "MySAXHandler.h"
#include <iostream>MySAX2Handler::MySAX2Handler()
{
}MySAX2Handler::~MySAX2Handler()
{
}void MySAX2Handler::startElement(const   XMLCh* const    uri,const   XMLCh* const    localname,const   XMLCh* const    qname,const   Attributes&     attrs)
{char* message = XMLString::transcode(qname);std::cout << "start element: " << message << std::endl;XMLString::release(&message);
}void MySAX2Handler::fatalError(const SAXParseException& exception)
{char* message = XMLString::transcode(exception.getMessage());std::cout << "Fatal Error: " << message<< " at line: " << exception.getLineNumber()<< std::endl;XMLString::release(&message);
}void MySAX2Handler::characters(const XMLCh* const chars, const XMLSize_t length)
{
}void MySAX2Handler::endElement(const XMLCh* const uri,const XMLCh* const localname,const XMLCh* const qname)
{char* message = XMLString::transcode(qname);std::cout << "end element: " << message << std::endl;XMLString::release(&message);
}
// main.cpp
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>#include "MySAXHandler.h"int main(int argc, char*  args[])
{try {XMLPlatformUtils::Initialize();}catch (const XMLException& toCatch){char* message = XMLString::transcode(toCatch.getMessage());std::cout << "Error during initialization! :\n";std::cout << "Exception message is: \n"<< message << "\n";XMLString::release(&message);return 1;}const char* xmlFile = "./data/personal.xml";SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();parser->setFeature(XMLUni::fgSAX2CoreValidation, true);parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);   // optionalparser->setFeature(XMLUni::fgXercesDynamic, false);parser->setFeature(XMLUni::fgXercesSchema, true);parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true);MySAX2Handler* defaultHandler = new MySAX2Handler();parser->setContentHandler(defaultHandler);parser->setErrorHandler(defaultHandler);parser->setEntityResolver(defaultHandler);try{parser->parse(xmlFile);}catch (const XMLException& toCatch){char* message = XMLString::transcode(toCatch.getMessage());std::cout << "Exception message is: \n"<< message << "\n";XMLString::release(&message);return -1;}catch (const SAXParseException& toCatch){char* message = XMLString::transcode(toCatch.getMessage());std::cout << "Exception message is: \n"<< message << "\n";XMLString::release(&message);return -1;}catch (...) {std::cout << "Unexpected Exception \n";return -1;}//defaultHandler->OutputPsList();delete parser;delete defaultHandler;XMLPlatformUtils::Terminate();system("PAUSE");return 0;}

运行结果:

XML解析之SAX方式相关推荐

  1. Java之xml解析(Sax方式)

    文章目录 一. Sax基本介绍: 二. java 编码实现解析xml Sax解析流程 DefaultHandler各方法介绍 XML与java对象之间的转换 1.xml文件的内容 2.XML与java ...

  2. Android[中级教程]第六章 XML解析之SAX解析器

    Android[中级教程]第六章 XML解析之SAX解析器 分类: Android中级2011-10-06 01:52 125人阅读 评论(1) 收藏 举报 接上一章,这一章我们就来学习SAX解析器, ...

  3. 关于XML解析的常用方式

    关于XML解析的方式(个人喜爱的方式,有些不常用的就不写了) 需要的jar包 dom4j / jaxen XML示例(该文件放置于src目录下) <?xml version="1.0& ...

  4. Java中解析XML文件之SAX方式

    1.SAX解析方式,是将XML文件逐行读进内存进行解析的. 2.首先编写一个SAXHandler(SAX处理类),这个类需要继承DefaultHandler类 3.在SAXHandler类中需要重写s ...

  5. xml解析:Sax,Dom,pull解析

    Sax 1.startDocument()文档开始 2.endDocument()文档结束 3.startElement(String namespaceURI,String localName,St ...

  6. iOS 中的 xml 解析

    在ios 中解析xml 的方法有很多种 1.苹果原生 NSXMLParser:SAX方式解析,使用简单 2.第三方框架 libxml2:纯c语言,默认包含在ios  sdk中,同时支持DOM 和 SA ...

  7. Java基础-xml解析

    XML XML 概述 Exendsible Markup Language(XML)可扩展标记语言 用途: 数据存储,小型数据库,存在一定CRUD操作可行性 网络数据的传输 JavaWEB项目配置文件 ...

  8. 关于Android中XML解析方式

    XML解析一般有三种方式:DOM .SAX.PULL. SAX解析器:它是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作.当事件源产生事件后,调用事件处理器相应的 ...

  9. XML的概述,.Dom4解析和SAX解析

    1.什么是XML XML 指可扩展标记语言(EXtensible Markup Language) html(hyper text markup langauge) XML 是一种标记语言,很类似 H ...

最新文章

  1. 模板 - 拓扑排序
  2. Android--解析XML之PULL
  3. 计算机系统的分类与发展方向
  4. 全球及中国增强现实产业战略布局及运营前景决策分析报告2021-2027年
  5. redis常见使用场景下PHP实现
  6. 【转】[完全免费] 在线UML Class Diagram 类图工具 - 教程第1部分
  7. When allowCredentials is true, allowedOrigins cannot contain the special value “*“ that cannot be
  8. Spring Boot + Spring Cloud 实现权限管理系统 配置中心(Config、Bus)
  9. hdu 1695GCD容斥
  10. 零基础学Arcgis(十二)地图标注与注记
  11. “长江第一灯光秀”引关注 景观工程首次应用4G 路由
  12. 第十届泰迪杯数据挖掘挑战赛A题解题思路附代码
  13. 华为模拟器eNSP防火墙配置vlan实验
  14. boot版本是什么 cent os_确定 BootROM 或固件版本
  15. 微信公众号开发--实现扫码关注公众号自动登录网站
  16. Python反爬机制-验证码
  17. Ubuntu下修改只读文件方法
  18. 刷了 1000 多道算法题,一点小小的心得!
  19. HTTP 新增的 103 状态码,这次终于派上用场了!
  20. ant man什么意思_ant是什么意思_ant翻译_读音_用法_翻译

热门文章

  1. ADAS/ADS 整车下线标定解决方案
  2. 3dmax:3dmax的软件中常用工具栏的选择并连接、绑定到空间扭曲、选择过滤器、视图坐标系、捕捉、对齐、层管理器等使用技巧之详细攻略
  3. 突破信息噪音:TOOM舆情监测系统为你解码大数据时代
  4. html漂浮图片代码关闭,js带关闭按钮的网页漂浮广告代码
  5. Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
  6. 通过锁装置实例了解SOLIDWORKS motion实体接触及马达的高级用法
  7. 算法设计与分析之近似算法
  8. 为什么越来越多人觉得“元宇宙”是个骗局?
  9. od机考题目-免单统计-第10讲:高频真题解析 III(上)
  10. 十分钟让你的javascript登峰造极