无废话SAX:十分钟了解sax基础

2024-04-27 22:32

本文主要是介绍无废话SAX:十分钟了解sax基础,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Sax 是事件驱动的 xml 简单接口。

要解析一份 xml 文档,而且在解析的过程中当某些事件发生时执行你希望此时执行的代码,就先准备以下三件事情。

l         获取一个 xml 解析器:到 xml.apache.org 免费获取。

l         获取 sax 类:上述的 xerces 解析器已经包括了,记得在 classpath 里包括他们。

l         获取一个 xml 文档:相信这个你自己可以搞定

接下来的事情,我认为以下的代码基本上说明了流程,其中要稍微解释的是 ContentHandler 接口。 SAX 2.0 定义了四个核心的处理接口,分别是 ContentHandler ErrorHandler DTDHandler EntityResolver 。其中较常用到的是前面两个,最后一个是处理 xml 里的实体的,而在 schema 较流行的今天, DTDHandler 也许不太需要注意。这些处理器可以被 set parser 上,当 parser 在解析 xml 文档的过程中,发生特定的事件时,处理器中对应的方法便会被调用,当然了,方法的内容由你来写。这个基本上就是 sax 的概要情况了。

在读完代码和自己运行过下面的代码后,我相信你对 sax 的工作方式已经了解了,剩下的事情就是自己去熟悉另外几个处理器的方法。希望这篇东西能让你快速了解 sax ,而还有不少的细节,还需要自己去慢慢探讨了。

public   class  Practice1 {

 

       
// 要实例化的reader的类名

       
private  String vendroParserClass  =   " org.apache.xerces.parsers.SAXParser " ;

 

       
// 被读取的xml文件路径,以bin为根目录。

       
private  String uri  =   " xmlDocuments/xmlPractise.xml " ;

 

       
// 为0时debugPrint方法不会打印数据。

       
private   final   int  debug  =   1 ;

 

       
public   void  test()  throws  IOException, SAXException {

              XMLReader reader 
=   null ;

              
try  {

                     
// 工厂方法以类名获得reader实例

                     reader 
=  XMLReaderFactory.createXMLReader(vendroParserClass);

              } 
catch  (Exception e) {

                     e.printStackTrace();

              }

              
// 以uri获取xml文档实例,reader.parse()方法可以接受一个

              // 简单的uri作为参数,但是InputSource会更好。

              InputSource inputSource 
=   new  InputSource(uri);

              
// 设置contentHandler

              reader.setContentHandler(
new  MyContentHandler());

              
// 执行读取

              reader.parse(inputSource);

              System.out.println(
" test completed. " );

       }

 

       
public   void  debugPrint(String msg) {

              
if  (debug  >   0 ) {

                     System.out.print(msg);

              }

       }

       
// 内容处理器

       
class  MyContentHandler  implements  ContentHandler {

              
// locator是定位器,指示当前解析文档进行到哪个位置了。

             // 它只在解析生命周期内有效,解析完毕就别再碰它咯~

              
private  Locator locator;

 

              
// 这个方法在整个解析过程的一开始被调用

public   void  setDocumentLocator(Locator locator) {

                     debugPrint(
" setDocumentLocator get called./n " );

                     
this .locator  =  locator;

              }

              

               // xml文档开始时被调用

              
public   void  startDocument()  throws  SAXException {

                     debugPrint(
" startDocument() get called./n " );

 

              }

              
// xml文档结束时被调用

              
public   void  endDocument()  throws  SAXException {

                     debugPrint(
" endDocument() get called./n " );

 

              }

               // xml文档的某个名称空间开始时被调用

              
public   void  startPrefixMapping(String prefix, String uri)

                            
throws  SAXException {

                     debugPrint(
" start of : uri:  "   +  uri  +   " , prefix:  "   +  prefix  +   " ./n " );

 

              }

              
// xml文档的某个名称空间结束时被调用

              
public   void  endPrefixMapping(String prefix)  throws  SAXException {

                     debugPrint(
" end of: uri:  "   +  uri  +   " , prefix:  "   +  prefix  +   " ./n " );

 

              }

              
// xml文档的某个元素开始时被调用

              
// uri是名称空间,localName是不带前缀的元素名,qName是前缀+元素名

              
// atts就是属性列表了。

              
public   void  startElement(String uri, String localName, String qName,

                            Attributes atts) 
throws  SAXException {

                     debugPrint(
" < "   +  localName  +   " > " );

 

              }

              
// xml文档的某个元素结束时被调用

              
public   void  endElement(String uri, String localName, String qName)

                            
throws  SAXException {

                     debugPrint(
" </ "   +  localName  +   " > " );

 

              }

              
// xml文档的某个元素的文本内容出现时被调用

            // start和length是字符串截取的开始位置和长度,如下所示是比较好的

               // 处理方法,先转换成String再处理

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

                            
throws  SAXException {

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

                     debugPrint(s);

                     

              }

            // 遇到可以忽略的空白时被调用,关于xml里的空白,可以长篇大论,

            // 这里就不废话了。

              
public   void  ignorableWhitespace( char [] ch,  int  start,  int  length)

                            
throws  SAXException {

                     
//  TODO Auto-generated method stub

 

              }

              
// 遇到xml的处理指令时被调用

              
public   void  processingInstruction(String target, String data)

                            
throws  SAXException {

                     debugPrint(
" PI target: ' "   +  target  +   " ', data: ' "   +  data  +   " '. " );

 

              }

              
// 当xml里的实体被非验证解析器忽略时被调用

              
public   void  skippedEntity(String name)  throws  SAXException {

                     
//  TODO Auto-generated method stub

 

              }

 

       }

 

       
public   static   void  main(String[] args)  throws  IOException, SAXException {

              
new  Practice1().test();

       }

}


题外话:以自己的学习的经历,感觉接触一门新技术的时候,详尽的经典著作未必最合适,如果要追求平缓的学习曲线,最好的方法是听学过的人谈谈整体的概念,看看运作实例,此时心中有了感性认识,再投入真正的学习中去,效果相当好。这也是写这篇东西的初衷了。文章很简陋,望勿见笑。


SAX is a event-driven simple api for xml.

There are three things to get before using SAX to parse a xml document, and make some code to execute when certain events comes up.

l        Get an xml parser: download it from xml.apache.org for free.

l        Get a SAX class: it should be included in the parser we mentioned above.

l        Get an xml document: get the white mouse yourself.

 

The following is quite self-explanative, the codes describe the basic flow. Only the ContentHandler interface needs a little bit words. SAX 2.0 defined 4 core handler interfaces: ContentHandler, ErrorHandler, DTDHandler, EntityResolver. The leading 2 are often used, the last one is for the entity in xml, while schema is more prefer now, DTDHandler needs not much attention. These handlers can be set to a parser, when the parser is parsing the xml file, some certain events take places, the corresponding methods will be called back. The content in these methods, of course, will be finished by you, that’s what call-back is. Then it is the brief of SAX.

After reading and running the following codes, I believed that you are clear about how SAX works, what’s left is that you shall get familiar with other handlers. I hope this stuff can help you understand SAX in a short time, the details are left to yourself.

 

 

public   class  Practice1 {

 

       
// name of the reader class that will be initialled.

       
private  String vendroParserClass  =   " org.apache.xerces.parsers.SAXParser " ;

 

       
// file path of the xml file,using bin as file root 。

       
private  String uri  =   " xmlDocuments/xmlPractise.xml " ;

 

       
// when this equasl 0, debugPrint() method won’t print message out。

       
private   final   int  debug  =   1 ;

 

       
public   void  test()  throws  IOException, SAXException {

              XMLReader reader 
=   null ;

              
try  {

                     
// using factory pattern 

                     reader 
=  XMLReaderFactory.createXMLReader(vendroParserClass);

              } 
catch  (Exception e) {

                     e.printStackTrace();

              }

              
// get a xml file instance using uri,reader.parse()method can accept a simple 

//  uri as a parameter, but InputSource is better。

              InputSource inputSource 
=   new  InputSource(uri);

              
// set the contentHandler

              reader.setContentHandler(
new  MyContentHandler());

              
// executing the parsing

              reader.parse(inputSource);

              System.out.println(
" test completed. " );

       }

 

       
public   void  debugPrint(String msg) {

              
if  (debug  >   0 ) {

                     System.out.print(msg);

              }

       }

       
// content handler

       
class  MyContentHandler  implements  ContentHandler {

              
// locator indicate the current position when parsing the file

// it is only valid during parsing, so don’t touch it after the parsing is finished

              
private  Locator locator;

 

              
// this method will be the first method called as the parsing begins.

public   void  setDocumentLocator(Locator locator) {

                     debugPrint(
" setDocumentLocator get called./n " );

                     
this .locator  =  locator;

              }

              

// this method will be called at the start of a xml file 

              
public   void  startDocument()  throws  SAXException {

                     debugPrint(
" startDocument() get called./n " );

 

              }

              
//  this method will be called at the end of a xml file

              
public   void  endDocument()  throws  SAXException {

                     debugPrint(
" endDocument() get called./n " );

 

              }

//  this method will be called at the start of a namespace

              
public   void  startPrefixMapping(String prefix, String uri)

                            
throws  SAXException {

                     debugPrint(
" start of : uri:  "   +  uri  +   " , prefix:  "   +  prefix  +   " ./n " );

 

              }

              
//  this method will be called at the end of a namespace

              
public   void  endPrefixMapping(String prefix)  throws  SAXException {

                     debugPrint(
" end of: uri:  "   +  uri  +   " , prefix:  "   +  prefix  +   " ./n " );

 

              }

              
//  this method will be called at the start of an element

              
public   void  startElement(String uri, String localName, String qName,

                            Attributes atts) 
throws  SAXException {

                     debugPrint(
" < "   +  localName  +   " > " );

 

              }

              
//  this method will be called at the end of an element

              
public   void  endElement(String uri, String localName, String qName)

                            
throws  SAXException {

                     debugPrint(
" </ "   +  localName  +   " > " );

 

              }

              
// x this method will be called when the text content appears

// start and length is the start index and length of the char array.

// parsed to a String before handling the content will be a good choice

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

                            
throws  SAXException {

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

                     debugPrint(s);

                     

              }

//  this method will be called when some ignorable white space appears,

//  there are much to talk about white space in xml, we aren’t talking them here.

              
public   void  ignorableWhitespace( char [] ch,  int  start,  int  length)

                            
throws  SAXException {

                     
//  TODO Auto-generated method stub

 

              }

              
//  this method will be called when processing instructions appears

              
public   void  processingInstruction(String target, String data)

                            
throws  SAXException {

                     debugPrint(
" PI target: ' "   +  target  +   " ', data: ' "   +  data  +   " '. " );

 

              }

//  this method will be called when the entity in the xml file is skipped by the  // parser.

              
public   void  skippedEntity(String name)  throws  SAXException {

                     
//  TODO Auto-generated method stub

 

              }

 

       }

 

       
public   static   void  main(String[] args)  throws  IOException, SAXException {

              
new  Practice1().test();

       }

}

这篇关于无废话SAX:十分钟了解sax基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/941702

相关文章

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

c++基础版

c++基础版 Windows环境搭建第一个C++程序c++程序运行原理注释常亮字面常亮符号常亮 变量数据类型整型实型常量类型确定char类型字符串布尔类型 控制台输入随机数产生枚举定义数组数组便利 指针基础野指针空指针指针运算动态内存分配 结构体结构体默认值结构体数组结构体指针结构体指针数组函数无返回值函数和void类型地址传递函数传递数组 引用函数引用传参返回指针的正确写法函数返回数组

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)