`
deepnighttwo
  • 浏览: 52183 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SAXP解析XML的笔记

阅读更多

 

SAXP 使用streaming 读取xml ,基于事件触发和回调函数处理xml 内容,占用内存小,速度快,适用于1 )仅仅读取但是不改变xml 内容 2 )只处理内容一次,类似于在xml 中查找相关内容。

创建Factory

解析xml 过程。首先需要创建factoryfactory 是用来创建parser 的,包含一些创建parser 的属性。

view source print ?

1

SAXParserFactory spfactory = SAXParserFactory.newInstance(); // 得到一个实例

view source print ?

1

spfactory.setSchema(schema);// setSchema 会使用schema 生成一个validator 来对被处理想xml 先进性验证,然后再发到handler 去处理

view source print ?

1

spfactory.setValidating(false);// 是否验证xml 文件,这个验证是DTD 验证,默认为false

view source print ?

1

spfactory.setNamespaceAware(false);//

2

这个对于handler 处理是有影响的,默认是false 。如果是true ,则parser 会首先处理xmlprefix ,找到与之对应的namespace ,然后作为参数传给handler 。否则namspace 就是空。

 

3

spfactory.setXIncludeAware(false);// 是否要处理xml 中的XInclude 节点,默认是false

还有一个可扩展的方法叫做setFeatures 。顾名思义,就是定制由这个factory 生成的parser 的功能。

比如下面这行代码:

view source print ?

1

saxfac.setFeature("http://xml.org/sax/features/namespace-prefixes ",

2

true);

 

setNamespaceAware=true 的时候,handler 默认将得不到xmlns 这些namespace 相关的属性。这个在大多数情 况下有道理,因为namespace 已经被parser 解析好了,handler 已经知道每个节点的namespace 了。但是如果还是需要完整的 attribute ,就比较抓狂了——debug 可以看到但是实际上已经被滤掉了。这时候需要设置了这个feature 之后才能得到。

创建parser

设置好相应的属性之后,就可以使用这个factory 的实例创建parser 了。

SAXParser saxParser = spfactory.newSAXParser();// 根据factory 的设置,创建一个saxpparser

有了parser ,可以设置不同的handler 来处理xml 。使用parser.getXMLReader() 得到一个XMLReader

用的最多的就是ContentHandlerContentHandler 是一个接口。创建出这个接口实现的实例后,可以将它设到parser 中,parser 在解析xml 的过程中,会根据事件来回调ContentHandler 中相应的方法。

view source print ?

1

xmlReader.setContentHandler(contentHandler);

除此之外还有setEntityResolver(EntityResolver) setDTDHandler(DTDHandler)setErrorHandler(ErrorHandler) 。这几个从来没有用过=_= 。有用过的人没?求usecase 。。。

ContentHandler 中相应的方法

ContentHandler 是处理xml 文档最重要的类。其中的方法会在特定的事件发生时候被触发。

view source print ?

01

startDocument(); // 此事件在开始解析文档的时候触发

02

 

 

 

03

endDocument(); // 此事件在文档解析结束后触发

04

 

 

 

05

startPrefixMapping(String prefix, String uri); // 此事件只有在setNamespaceAwaretrue 的时候才会被触发。每次遇到xmlns 属性后都会触发一次。prefix 为去掉xmlns 之后的内容,uri 就是这个前缀对应的namespace 。所以,如果想在setNamespaceAwaretrue 的时候还得到这 些attribute ,除了setFeature 之外,也可以处理这个事件,保存相应的prefix-uri mapping

06

 

 

 

07

endPrefixMapping(String prefix); // 此事件在包含xmlns attribute 的节点结束之后被触发。对于wsdl 来说,就是在触发了wsdl:definitionsendElement 之后触发。

08

 

 

 

09

startElement(String uri, String localName, String qName, Attributes atts); // 在一个node 开始的时候触发。如果setNamespaceAwaretrue ,那么uri 的值就会被resolve ,否则就会是空。 localName 则是节点的名字,比如对于wsdl:definitions 来说,就是definitionsqName 就是node 的全名,比如 wsdl:definitionsatts 就是这个node 的所有属性。但是这时候会没有xmlns 的属性。如果setNamespaceAware false ,那么就不对uri 解析。uri 就是空,localName 也是空,qName 就是xs:sequence 这种节点的名字。atts 则会返回节 点所有属性的k-v mapping

10

 

 

 

11

endElement(String uri, String localName, String qName); // 在节点处理完毕后触发。参数值与startElement 意义相同。

12

 

 

 

13

characters(char ch[], int start, int length); // node 的开始结束之前如果有字符,则会触发此事件。比如 <nodeA>some character</nodeA> 。在startElement nodeA 之后,endElement nodeA 之前,会调用characters 方法,用new String(ch, start, length) 创建出来的字符串就是"some character" 。这个方法需要注意的一点是,如果节点中的内容有多行,那么这个方法有可能会被调用多次。也就是可能会(没有验证过)每一行都调用一 次characters 。还有需要注意的一点是,创建出来的字符串已经包含了回车换行

14

 

 

 

15

ignorableWhitespace(char[], int, int); // 文档说Receive notification of ignorable whitespace in element content. 具体啥意思没试过。好像和validator 有关。求解答。。。

16

 

 

 

17

processingInstruction(String target, String data); // xmlPI 的时候被触发。但是xml 最开始的PI 不会触发,就是那个<?xml version="1.0" encoding="UTF-8"?> ,是不会触发此事件的。除此之外,xml 里的PI 都会被处理。比如<?testpi key1="value1" key2="value2"?> 就会被触发两次,target 都是testpidata 两次分别是key1="value1" key2="value2"

18

 

 

 

19

skippedEntity(String); // 文档说Receive notification of a skipped entity. 不知道啥意思,求解答。。。

20

 

 

 

21

setDocumentLocator (Locator locator); // 这个方法也很有用,parser 会在处理文档之前调用此方法。如果你需要知道当前处理到文档的第几行第几列,就需要实现这个方法。实现不需要做什么处理, 只要在自己的ContentHandler 里创建一个Locator 类型的成员变量,用这个成员变量保存传进来的参数,然后记得调用 super.setDocumentLocatorparser 会实时更新Locator 中的变量值。通过LocatorgetLineNumber getColumnNumber 可以得到当前处理的行和列。还有publicIDsystemID ,不知道是做啥用的。

基本上这些内容就够解析xml 用的了。

顺道问问题

除了文章中说的几个不清楚之外,还有个问题一直想知道答案。SAXP 处理xml ,一般处理一点就找到要找的东西了,下面一大半xml 就不用处理了, 那有没有什么办法让parser 终止继续处理?做个boolean 标记,parser 总归还是要把xml 走一遍的,如果xml 很大,或者是远程的xml , 那么就会比较有用了。

stackoverflow 上找到了解答 http://stackoverflow.com/questions/2964315/java-sax-parser-how-to-manually-break-parsing

简单来说就是在处理完毕,确定不需要继续处理的时候,直接抛个异常。。。

 

 

分享到:
评论

相关推荐

    java在线解析xmljava在线解析xmljava在线解析xmljava在线解析xml

    java在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava...

    PB 解析XML (代码案例)

    标题中的“PB 解析XML”指的是使用PowerBuilder(简称PB)这一编程工具处理XML数据的过程。PowerBuilder是一款广泛用于开发企业级应用的可视化编程环境,它支持多种数据格式,包括XML。XML(eXtensible Markup ...

    SAX解析XML文件实例

    SAX解析XML文件的实例。一个项目同时用dom解析和sax解析xml文件貌似会报错,项目框架建一直是用sax和dom4j解析xml文件的。当我用dom解析xml文件。导入包后就报错识别不了xml文件的编码格式。于是做了一个sax解析xml...

    JAVA 解析XML生成XML文档实例

    JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

    STM32解析XML

    在本文中,我们将深入探讨如何在STM32F107上使用minixml库解析XML(可扩展标记语言)文档,这对于那些初次尝试在嵌入式环境中处理XML数据的开发者来说,是非常有价值的。 XML是一种通用的数据交换格式,它允许结构...

    PB 解析xml格式串

    2. **XML解析**:XML文档由元素、属性、文本等构成,解析XML时,我们需要读取这些元素并将其转换为内存中的数据结构。Python中可以使用`xml.etree.ElementTree`库进行解析,Java中可使用DOM或SAX解析器。 3. **XML...

    kettle 解析xml xml文档,配合kettle 解析xml stax方法,完整解析案例使用

    与上一个版本一起使用可以可以起到提高效率的目的。本人解析xml的真实文档

    C++解析xml文件

    本文将深入探讨如何使用C++来解析XML文件,主要围绕“C++实现对xml文件的解析”这一主题展开。 XML文件通常包含一系列元素,每个元素都有开始标签、结束标签和可能的属性。C++中解析XML文件的方法多种多样,这里...

    易语言 xml解析 易语言 xml解析 教程 带源码

    易语言XML解析是编程领域中的一个重要主题,尤其对于使用易语言进行开发的程序员来说,理解并掌握XML(可扩展标记语言)的解析方法是至关重要的。XML作为一种结构化数据存储和交换格式,广泛应用于网络通信、配置...

    js解析XML文件

    JS 解析 XML 文件 作为一名 IT 行业大师,我将从给定的文件中生成相关知识点,涵盖 JS 解析 XML 文件的各种方面。 JS 解析 XML 文件的必要性 在当前的 web 开发中,XML 文件广泛应用于数据交换和存储。因此,如何...

    解析xml的jar包

    解析XML是将XML文档转换为程序可以理解的数据结构的关键步骤。本文将深入探讨XML解析的基本概念、常用方法以及相关的Java库——JDOM。 XML文档由一系列元素构成,每个元素都包含标签、属性和内容。解析XML的过程...

    STM32解析XML完整工程.zip

    在本项目"STM32解析XML完整工程.zip"中,重点是实现STM32利用软件资源处理XML(eXtensible Markup Language)文件。XML是一种用于标记数据的标准格式,常用于存储和传输结构化数据,例如配置文件、设备通信协议等。 ...

    C++解析xml文档或者xml字符串方法

    在C++中,解析XML文档或XML字符串是常见的任务,特别是在需要与JavaScript或其他不支持指针的语言交互时。本文将详细介绍如何在Visual Studio 2010环境下利用Microsoft的MSXML库来处理XML数据。 首先,让我们看看...

    java 解析xml 多级

    Java作为一种广泛使用的后端编程语言,提供了多种方式来解析XML文档,使得处理多级嵌套的数据变得可能。本文将详细讲解如何在Java中解析XML,特别是针对多级结构的情况。 首先,Java提供了两种主要的API来处理XML:...

    解析xml和本地解析xml

    本文将深入探讨“在线解析XML”与“本地解析XML”的概念及其应用场景,以及如何将XML数据从CLOB字段提取并存入数据库。 1. XML的基本概念: XML是一种自描述的、结构化的文本格式,它通过标签来定义数据结构和内容...

    android下解析xml文件的demo

    在Android应用中,我们通常使用两种方式来解析XML:DOM(Document Object Model)解析器和SAX(Simple API for XML)解析器。 1. DOM解析: DOM解析器将整个XML文件加载到内存中,形成一个树形结构,可以方便地遍历...

    Sax解析XML文件解析

    SAX(Simple API for XML)是XML解析的一种方法,它以事件驱动的方式处理XML文档,非常适合处理大体积的XML文件,因为它不需要一次性加载整个文件到内存,而是逐行读取,因此节省了资源。 **SAX解析XML的基本原理:...

    delphi解析xml文件实例

    Delphi是一款强大的Object Pascal编程环境,它提供了丰富的库和工具来处理XML数据,包括解析、创建和操作XML文档。本实例将详细探讨如何在Delphi 7中解析XML文件。 首先,我们需要引入必要的单元,如`Classes`和`...

    STM32使用ezxml解析XML文件

    然而,由于资源限制,STM32往往没有内置专门用于XML解析的硬件模块,因此需要软件库来处理XML文件。在这种背景下,ezxml库应运而生。 ezxml库是一个轻量级的C语言XML解析库,设计用于嵌入式环境,包括STM32这类微...

    kettle 解析xml多层次流式解析

    kettle 解析xml多层次流式解析,描述了复杂情况下流式解析需要注意的点。

Global site tag (gtag.js) - Google Analytics