`
lwj0212
  • 浏览: 49627 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

学习笔记-理解sax

    博客分类:
  • xml
阅读更多
SAX 是什么?

用于读取和操作 XML 文件的标准是文档对象模型(Document Object Model,DOM)。遗憾的是,DOM 方法涉及读取整个文件并将该文件存储在一个树结构中,而这样可能是低效的、缓慢的,并且很消耗资源。

一种替代技术就是 Simple API for XML,或称为 SAX。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。

SAX 是由 XML-DEV 邮件列表的成员开发的,现在对应的 Java 版本是 SourceForge 项目(请参阅 参考资料)。该项目的目的是为 XML 的使用提供一种更自然的手段 —— 换句话说,也就是不涉及 DOM 所必需的开销和概念跳跃。

项目的成果是一个基于事件 的 API。解析器向一个事件处理程序发送事件,比如元素的开始和结束,而事件处理程序则处理该信息。然后应用程序才能够处理该数据。原始的文档仍然保持原样,但是 SAX 提供了操作数据的手段,因此数据可以用于另一个进程或文档。

SAX 没有官方的标准机构,由万维网联盟(Wide Web Consortium,W3C)或其他官方机构维护,但它是 XML 社区事实上的标准。
  • SAX 处理涉及以下步骤:

  •    1. 创建一个事件处理程序。
       2. 创建 SAX 解析器。
       3. 向解析器分配事件处理程序。
       4. 解析文档,并将每个事件发送到事件处理程序。
    基于事件的处理的优点和缺点

    这种处理的优点非常类似于流媒体的优点。不需要等待所有数据都处理完成,就可以立即开始分析。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX 比 DOM 快许多。

    另一方面,由于应用程序没有以任何方式存储数据,使用 SAX 来更改数据或在数据流中往后移是不可能的。
  • DOM 和基于树的处理

  • DOM 是处理 XML 数据的传统方法。使用 DOM 时,数据以树状结构的形式被加载到内存中
    基于树的处理的优点和缺点

    DOM 以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此修改它可以使应用程序对数据和结构作出更改。它还可以随时在树中上下导航,而 SAX 是一次性的处理。此外,DOM 使用起来也简单很多。

    另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况并不少见。此外,创建 DOM 树非常耗时
  • 如何在 SAX 和 DOM 之间选择

  • 选择 DOM 还是选择 SAX 取决于下面几个因素:

        * 应用程序的用途:如果打算对数据作出更改并将它输出为 XML,DOM 通常是适当的选择。并不是说 SAX 不能更改数据,而是操作起来复杂得多,因为您必须更改数据的拷贝而不是数据本身。
        * 数据量:对于大型文件,SAX 是更好的选择。
        * 数据使用的方式:如果只使用数据的少量部分,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。另一方面,如果您需要回头引用已处理过的大量信息,那么应该选择 DOM。
        * 速度要求:SAX 实现通常要比 DOM 实现更快。

    重要的是,SAX 和 DOM 并不相互排斥。您可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。事实上,用于创建 DOM 树的大多数解析器实际上都使用 SAX 来完成这个任务!

使用样例
public class XmlDocumentUtil {
	public static void main(String[] str) throws Exception {
		XmlDocumentUtil xmlUtil=new XmlDocumentUtil();
		//xmlUtil.XmlFilterReader();
		//xmlUtil.serializerXml();
		xmlUtil.readXml();
	}
	public void readXml() {
		
		
		DocumentBuilderFactory xmlBuild=DocumentBuilderFactoryImpl.newInstance();
		//DocumentBuilderFactory.newInstance();
		xmlBuild.setValidating(false);
		xmlBuild.setIgnoringComments(true);
		xmlBuild.setIgnoringElementContentWhitespace(true);
		try {
			File xml=new File("atta.xml");
			DocumentBuilder build=xmlBuild.newDocumentBuilder();
			build.setEntityResolver(new DefaultEntityResolver());
			Document doc= build.parse(xml);
			//ErrorHandlerWrapper
			Element root=doc.getDocumentElement();
			NodeList nodeList=root.getChildNodes();
			/*for(int i=0;i<nodeList.getLength();i++){
				Node node=(Node)nodeList.item(i);
				System.out.println(node.getNodeName()+":"+node.getNodeValue());
			}*/
			
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * <p>功能:创建xml解析器<p>
	 * <p>
	 * <p>
	 */
	public void CreaterXmlreader() {
		try {
			/*方法1、获取xmlReader*/
			XMLReader xmlReader= XMLReaderFactory.createXMLReader();
			
			/*方法2、获取xmlReader*/
			SAXParserFactory saxParserF=SAXParserFactory.newInstance();
			saxParserF.setValidating(false);
			
			SAXParser saxParser=saxParserF.newSAXParser();
			xmlReader=saxParser.getXMLReader();
			
			/*解析文档*/
			xmlReader.setContentHandler(new XmlReaderHandler());
			
			xmlReader.parse("");
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void serializerXml() throws ParserConfigurationException, SAXException, IOException{
		SAXParserFactory spfFactory=SAXParserFactory.newInstance();
		spfFactory.setValidating(false);
		SAXParser saxParser=spfFactory.newSAXParser();
		
		XMLReader xmlReader= saxParser.getXMLReader();
		/*可接受xml,txt,html*/
		Serializer serializer=SerializerFactory.getSerializer(OutputProperties.getDefaultMethodProperties("xml"));
		serializer.setOutputStream(new FileOutputStream("output.xml"));
		
		InputSource inSource=new InputSource("atta.xml");
		xmlReader.parse(inSource);
		
		
	}
	
	public void XmlFilterReader() throws SAXException, ParserConfigurationException, IOException{
		SAXParserFactory spfFactory=SAXParserFactory.newInstance();
		spfFactory.setValidating(false);
		SAXParser saxParser=spfFactory.newSAXParser();
		
		XMLReader xmlReader= saxParser.getXMLReader();
		
		XmlFilter xmlFilter=new XmlFilter(xmlReader);
		//xmlFilter.setParent(xmlReader);
		
		xmlFilter.setContentHandler(new XmlFilter());
		xmlFilter.setErrorHandler(new XmlFilter());
		
		InputSource inSource=new InputSource("atta.xml");
		
		xmlFilter.parse(inSource);
	}
	/*转换xml*/
	public void sampleTransFormXml() throws ParserConfigurationException, SAXException, TransformerConfigurationException, IOException{
		SAXParserFactory saxPF=SAXParserFactory.newInstance();
		saxPF.setValidating(false);
		SAXParser saxParser=saxPF.newSAXParser();
		
		XMLReader xmlReader=saxParser.getXMLReader();
		
		TransformerFactory tfF=TransformerFactory.newInstance();
		//Transformer tf=tfF.newTransformer();
		SAXTransformerFactory saTF=(SAXTransformerFactory)tfF;
		XMLFilter filter=saTF.newXMLFilter(new StreamSource("atta.xsl"));
		filter.setParent(xmlReader);
		
		Serializer serializer=SerializerFactory.getSerializer(OutputProperties.getDefaultMethodProperties("xml"));
		serializer.setOutputStream(System.out);
		
		filter.setContentHandler(serializer.asContentHandler());
		
		InputSource inputSource=new InputSource("atta.xml");
		filter.parse(inputSource);
	}
	
}
class XmlFilter extends XMLFilterImpl{

	@Override
	public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
		super.startElement(arg0, arg1, arg2, arg3);
	}
	public XmlFilter(XMLReader xmlReader){
		super(xmlReader);
	}
	
	public XmlFilter(){
		super();
	}
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		System.out.println("[xml filter] startDocument");
	}
	
	
}
class XmlReaderHandler extends DefaultHandler{

	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		System.out.println("start parser document");
	}

	@Override
	public void error(SAXParseException arg0) throws SAXException {
		super.error(arg0);
	}
	
}


名称空间

SAX 20 版的一个主要增强是添加了对名称空间的支持,从而允许开发人员无冲突地使用来源不同或用途不同的信息。这通常出现在生产环境中,因为生产环境中的 SAX 数据流中的数据来源非常广泛。

名称空间是一个概念范围,其中的所有名称都必须是唯一的。

例如,我过去常在这样一间办公室工作,我的名字和那里的一位客户相同。如果我在办公室,而接待员宣布 “Nick,请接 1 号电话”,那么每个人都知道她指的是我,因为我在 “办公室名称空间中”。类似地,如果她宣布 “Nick 在一号线上”,每个人都知道她指的是那位客户,因为呼叫者在办公室名称空间之外。

另一方面,如果我出了办公室,而她做出相同的宣布,混淆就可能产生,因为两种可能性都存在。

当 XML 数据库由多种来源组合而成时,同样的问题也会产生,比如本教程稍后将会详细描述的示例文件中修订过的调查信息。
由于名称空间的标识符必须是唯一的,因而使用统一资源定位符(或 URI)来指定它们。例如,本教程的示例数据的默认名称空间将使用 xmlns 属性来指定:

<?xml version="1.0"?>
<surveys  xmlns="http://www.nicholaschase.com/surveys/" >
<response username="bob">
   <question subject="appearance">A</question>
...


没有指定名称空间的任何节点都在默认名称空间 http://www.nicholaschase.com/surveys/ 中。实际的 URI 本身并没有表示任何意义。信息可能在也可能不在该地址,重要的是它必须是唯一的。

默认名称空间和没有名称空间之间的巨大区别是很重要的。在本例中,没有名称空间前缀的元素都在默认名称空间中。以前,当不存在默认名称空间时,那些元素就不在任何名称空间中。当您处理 关于属性的名称空间 时,这个区别就变得重要了。

您还可以创建次级名称空间,并向它们添加元素或属性。
指定名称空间

也可以为数据指定其他名称空间。例如,通过创建一个 revised 名称空间,您可以添加第二组数据,比如后期催眠,而不干扰原先的数据。

通常在文档的根元素上(但不是必须的)创建名称空间及其别名。当正在使用多个名称空间时,这个别名根据需要用作元素或属性的前缀,以指定正确的名称空间。请考虑下面代码:

<?xml version="1.0"?>
<surveys xmlns="http://www.nicholaschase.com/surveys/"
         xmlns:revised="http://www.nicholaschase.com/surveys/revised/">
<response username="bob">
   <question subject="appearance">A</question>
   <question subject="communication">B</question>
   <question subject="ship">A</question>
   <question subject="inside">D</question>
   <question subject="implant">B</question>

   <revised:question subject="appearance">D</revised:question>
   <revised:question subject="communication">A</revised:question>
   <revised:question subject="ship">A</revised:question>
   <revised:question subject="inside">D</revised:question>
   <revised:question subject="implant">A</revised:question>
  
</response>
<response username="sue">
...


它使用了名称空间和别名 revised 来创建额外的 question 元素。

记住 revised: 不是名称空间,而是别名!实际的名称空间是 http://www.nicholaschase.com/surveys/revised/。


属性也可能属于某个特定的名称空间
即使声明了一个默认名称空间,没有前缀的属性也被认为是没有名称空间。这只是在 XML 推荐标准中定义的一个例外
名称空间的奇怪之处

SAX 解析器处理本地名称和 QName 的方式可能有点奇怪。例如,除非专门打开名称空间处理,否则默认的 Java 解析器就不会报告本地名称的值:

   try {

      SAXParserFactory spfactory = SAXParserFactory.newInstance();
      spfactory.setValidating(false); 
 spfactory.setFeature("http://xml.org/sax/features/namespace-prefixes", 
              true);
      spfactory.setFeature("http://xml.org/sax/features/namespaces", 
              true);
         
      SAXParser saxParser = spfactory.newSAXParser();


如果不能获取信息,可尝试设置解析器的这些特性。
分享到:
评论

相关推荐

    java lecture note(Java学习笔记)

    本篇Java学习笔记旨在为读者提供一个深入理解Java的基础与进阶知识的框架,帮助初学者及有一定经验的开发者提升Java编程技能。 ### 一、Java入门与基本语法 #### 课程概述 Java课程旨在介绍面向对象编程的基本原则...

    Dom4j学习教程+API+xml实用大全+xml学习笔记+htc

    4. **学习笔记**: 学习笔记通常包含个人理解、实例代码和问题解决方案,对于初学者来说是很好的参考资料,可以了解他人在学习过程中遇到的问题和解决办法。 5. **API(应用程序接口)**: Dom4j的API文档是开发者的...

    dom4j 学习笔记

    **DOM4J学习笔记** DOM4J是一个强大的Java XML API,它提供了丰富的XML处理功能,包括文档构建、解析、修改和查询。作为一个开源项目,DOM4J在XML处理领域具有广泛的用户基础,因其简单易用和高效性能而备受青睐。...

    北京圣思园xml学习笔记

    ### 北京圣思园XML学习笔记核心知识点详解 #### XML概述 - **XML全称**:eXtensible Markup Language(可扩展标记语言) - **学习XML的原因**: - 数据交换的需求日益增长,XML成为了电子商务的重要基础之一。 - ...

    Xml高级学习笔记

    【XML 高级学习笔记】 XML(Extensible Markup Language)是一种可扩展标记语言,与HTML类似,但其设计目标是存储和传输数据,而非呈现数据。XML允许用户自定义标签,使得它成为一种自描述的语言,并且是W3C的标准...

    corejava的学习笔记

    这份学习笔记涵盖了从操作系统基础到数据库应用的广泛主题,是Java初学者或希望巩固基础的开发者的重要资源。 1. **Unix学习基础**:Unix是许多服务器和开发环境常用的操作系统。了解Unix的基础知识,包括文件系统...

    MLDN学习笔记 —— XML学习笔记

    XML,全称Extensible Markup Language,可扩展标记语言,是一种用于标记数据的结构化语言,...通过这些学习资料,你将能够深入理解XML的各个方面,从基础语法到高级用法,从而在实际工作中更有效地处理和利用XML数据。

    css-html-jsp-xml学习笔记

    【CSS】 ...CSS描述了如何在媒体(如屏幕、打印机)上展示元素。通过CSS,你可以控制网页的...这些笔记涵盖了Web开发的基础知识,适合初学者入门,通过学习和实践,可以逐步掌握创建动态、响应式和数据驱动的网页应用。

    Dom4j学习笔记

    **标题解析:** "Dom4j学习笔记" 这个标题明确指出了我们要探讨的主题——Dom4j。Dom4j是一个流行的Java库,用于处理XML文档。它提供了丰富的API,使得XML的读取、写入、操作变得简单易行。在学习笔记中,通常会涵盖...

    Java JDK 6学习笔记——ppt简体版.rar

    这份"Java JDK 6学习笔记——ppt简体版"提供了关于这个关键版本的详细教程,适合初学者和有一定经验的开发者来深入理解Java编程。 首先,我们要了解Java JDK是什么。Java Development Kit,简称JDK,是Oracle公司...

    《轻松搞定XML》的范例源代码和学习笔记

    在本资源包中,你将找到《轻松搞定XML》这本书的学习笔记和配套源代码,这些都是作者在深入研读过程中积累的宝贵资料。 XML的核心特性包括自描述性、结构化和平台及语言无关性。自描述性意味着每个元素都有自己的...

    Java JDK 6学习笔记

    Java JDK 6学习笔记是针对Java开发环境的重要参考资料,它涵盖了Java Development Kit(JDK)6版本的关键特性和...这份学习笔记将指导读者逐步探索和理解Java编程世界的深度和广度,为日后的开发工作打下坚实的基础。

    java学习笔记JDK6课件和课本代码

    这个"java学习笔记JDK6课件和课本代码"资源很可能是包含了一系列的教程、PPT课件、示例代码和练习题,帮助初学者或者需要回顾JDK 6特性的开发者深入理解和实践。通过这些资料,你可以学习如何使用JDK 6中的新功能,...

    dom4j学习笔记

    **DOM4J学习笔记** DOM4J是一个Java库,它提供了强大的XML处理功能,包括解析、操作和生成XML文档。这个库是开源的,广泛应用于Java应用程序中,特别是在需要处理XML数据时。DOM4J的设计目标是易于使用,同时保持高...

    XSLT自动代码生成学习笔记

    **XSLT自动代码生成学习笔记** XSLT(Extensible Stylesheet Language Transformations)是一种强大的XML转换语言,常用于将XML数据转换成其他格式,如HTML、PDF或纯文本。在软件开发中,XSLT被广泛应用于自动代码...

    jsp学习笔记

    ### JSP学习笔记:重点知识点解析 #### 一、JSP简介 JSP(JavaServer Pages)是一种基于Java技术的动态网页技术标准。它通过在传统的HTML页面中嵌入Java代码来实现动态内容的生成。JSP页面最终会被转换成Servlet,...

Global site tag (gtag.js) - Google Analytics