读取一个大文件,能否通过SAX从读取流中一点一点sax写入换行到xml中,而不是全部一次性写出?

> java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXB
java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXB
相关推荐:/topic/6682801. DOM(Document Object Model)此 方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点 。 因此非常消耗系统性能 ,对比较大的文档不适宜采用DOM方法来解析。 DOM
Java中解析XML的工具很多,像JDOM,DOM4J等,但Java标准库提供的两种解析XML文档解析器是:DOM(Document Object Module)解析器 和 SAX(Simple API for XML)解析器。DOM解析器会读入整个XML文档并转换成树结构;SAX解析器会在读入XML文档时生成相应的事件;故也常叫基于文档对象模型的XML解析和基于事件驱动的XML解析;那它们有什么区别呢?DOM解析器会读入整个文档,构建一个驻留在内存中的树型结构,我们就可以使用 DOM 接口来操作这个文档树,其优点是整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能;缺点是需将整个文档读入内存中,在文档大时会消耗大量内存;SAX解释器在XML文档读入时能够立即开始,而不是等待所有的数据加载完后处理,解析器通过发现元素开始、元素结束、文本开始、文档结束等来发送事件,通过种基于回调机制的方法来处理数据;其优点是解析速度快,不用事先调入整个文档,占用资源少;其缺点是必须实现事件处理程序,不能修改文档,不能随机访问。DOM4J性能最好,连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.我们就细细的研究这几种方式吧。主要有4种:DOM、SAX、JDOM、JAXB1.DOM(Document Object Model)此 方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点 。 因此非常消耗系统性能 ,对比较大的文档不适宜采用DOM方法来解析。 DOM API 直接沿袭了 XML 规范。每个结点都可以扩展的基于 Node 的接口,就多态性的观点来讲,它是优秀的,但是在 Java 语言中的应用不方便,并且可读性不强,著名的SPRING框架就是采用此方法读取XML。首先来了解点Java DOM 的 API:1.解析器工厂类:DocumentBuilderFactory创建的方法:DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();2.解析器:DocumentBuilder创建方法:通过解析器工厂类来获得 DocumentBuilder db = dbf.newDocumentBuilder();3.文档树模型Document创建方法:a.通过xml文档 Document doc = db.parse(&bean.xml&);b.将需要解析的xml文档转化为输入流 InputStream is = new FileInputStream(&bean.xml&); Document doc = db.parse(is); Document对象代表了一个XML文档的模型树,所有的其他Node都以一定的顺序包含在Document对象之内,排列成一个树状结构,以后对XML文档的所有操作都与解析器无关,直接在这个Document对象上进行操作即可; 包含的方法:4.节点列表类NodeListNodeList代表了一个包含一个或者多个Node的列表,根据操作可以将其简化的看做为数组5.节点类NodeNode对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少会直接使用Node对象,而是使用Node对象的子对象Element,Attr,Text等6.元素类Element是Node类最主要的子对象,在元素中可以包含属性,因而Element中有存取其属性的方法Node.getNamespaceURI() 返回和给定节点关联的名称空间字符串,如果该元素或属性没有关联的名称空间则返回 null。7.属性类Attr代表某个元素的属性,虽然Attr继承自Node接口,但因为Attr是包含在Element中的,但并不能将其看做是Element的子对象,因为Attr并不是DOM树的一部分基本的知识就到此结束,更加具体的大家可以参阅JDK API文档 实例: Java代码import javax.xml.parsers.*;//XML解析器接口import org.w3c.dom.*;//XML的DOM实现import org.apache.crimson.tree.XmlD//写XML文件,很明显该类是一个单例,先获取产生DocumentBuilder工厂的工厂,在通过这个工厂产生一个DocumentBuilder,DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//允许名字空间factory.setNamespaceAware(true);//允许验证factory.setValidating(true);//获得DocumentBuilder的一个实例try {DocumentBuilder builder = factory.newDocumentBuilder();} catch (ParserConfigurationException pce) {System.err.println(pce);//出异常时输出异常信息,然后退出,下同System.exit(1);}//解析文档,并获得一个Document实例。try {//Document可以看作是XML在内存中的一个镜像,那么一旦获取这个Document 就意味着可以通过对//内存的操作来实现对XML的操作,首先第一步获取XML相关的DocumentDocument doc = builder.parse(fileURI);} catch (DOMException dom) {System.err.println(dom.getMessage());System.exit(1);} catch (IOException ioe) {System.err.println(ioe);System.exit(1);}//获得根节点StuInfo,在xml文件里,只有一个根元素,先把根元素拿出来看看Element elmtStuInfo = doc.getDocumentElement();//得到所有student节点NodeList nlStudent = elmtStuInfo.getElementsByTagNameNS(strNamespace, &student&);for (……){//当前student节点元素Element elmtStudent = (Element)nlStudent.item(i);NodeList nlCurrent =elmtStudent.getElementsByTagNameNS(strNamespace, &name&);}对于读取得方法其实是很简单的,写入xml文件也是一样不复杂。Java代码DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder =try {builder = factory .newDocumentBuilder();} catch (ParserConfigurationException pce) {System.err.println(pce);System.exit(1);}Document doc =doc = builder .newDocument();//下面是建立XML文档内容的过程,//先建立根元素&学生花名册&Element root = doc.createElement(&学生花名册&);//根元素添加上文档doc.appendChild(root);//建立&学生&元素,添加到根元素Element student = doc.createElement(&学生&);student.setAttribute(&性别&, studentBean.getSex());root.appendChild(student);//建立&姓名&元素,添加到学生下面,下同Element name = doc.createElement(&姓名&);student.appendChild(name);Text tName = doc.createTextNode(studentBean.getName());name.appendChild(tName);Element age = doc.createElement(&年龄&);student.appendChild(age);Text tAge = doc.createTextNode(String.valueOf(studentBean.getAge()));age.appendChild(tAge);2.SAX (Simple API for XML)此方法主要由XML-DEV 邮件列表的成员开发的,SAX是基于事件的方法,它很类似于标签库的处理机制,在标签开始、结束以及错误发生等等地方调用相应的接口实现方法,不是全部文 档都读入内存。 SAX具有优异的性能和利用更少的存储空间特点。SAX 的设计只考虑了功能的强大性,却没有考虑程序员使用起来是否方便。使用必须扩展ContentHandler、ErrorHandler、DTDHandler等,但是必须扩展ContentHandler(或者DefaultHandler )。 Java代码import org.xml.sax.*;publicclassMyContentHandler implements ContentHandler {… …}/*** 当其他某一个调用事件发生时,先调用此方法来在文档中定位。* @param locator*/public void setDocumentLocator(Locator locator){}/*** 在解析整个文档开始时调用* @throws SAXException*/public void startDocument() throws SAXException{System.out.println(&** Student information start **&);}/*** 在解析整个文档结束时调用* @throws SAXException*/public void endDocument() throws SAXException{System.out.println(&**** Student information end ****&);}/*** 在解析名字空间开始时调用* @param prefix* @param uri* @throws SAXException*/public void startPrefixMapping(String prefix, String uri) throws SAXException{}/*** 在解析名字空间结束时调用* @param prefix* @throws SAXException*/public void endPrefixMapping(String prefix) throws SAXException{}/*** 在解析元素开始时调用* @param namespaceURI* @param localName* @param qName* @param atts* @throws SAXException*/public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException{}/** 在解析元素结束时调用* @param namespaceURI* @param localName 本地名,如student* @param qName 原始名,如LIT:student* @throws SAXException*/public void endElement(String namespaceURI, String localName,String qName) throws SAXException{if (localName.equals(“student”)){System.out.println(localName+&:&+currentData);}}取得元素数据的方法——characters 取得元素数据中的空白的方法——ignora相关推荐:在java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXB1. DOM(Document Object Model)此 方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点 。 因此非常消耗系统性能 ,对比较大的文档不bleWhitespace在解析到处理指令时调用的方法——processingInstruction当未验证解析器忽略实体时调用的方法——skippedEntity运行时,只需要使用下列代码: Java代码MySAXParser mySAXParser = new MySAXParser();mySAXParser.parserXMLFile(&SutInfo.xml&);3.JDOM JDOM的处理方式有些类似于DOM,但它主要是用SAX实现的 。JDOM用Java的数据类型来定义操作数据树的各个节点 。JDOM的性能也很优越。 Java代码import org.jdom.*;import org.jdom.input.*;import org.jdom.output.*;SAXBuilder builder = new SAXBuilder(false);//得到DocumentDocument doc = builder.build(fileURI);//名字空间Namespace ns = Namespace.getNamespace(&LIT& , &http://www./student/ &);//取得所有LIT:student节点的集合List lstStudents = elmtStuInfo.getChildren(&student&,ns);for ( … ){Element elmtStudent = (Element)lstStudents.get(i);elmtStudent.getChildTextTrim(&name&, ns);}//修改elmtLesson.getChild(&lessonScore& , ns).setText(&100&);//删除elmtStuInfo.removeChild(&master&, ns);//添加elmtStuInfo.addContent(new Element(&master& , ns).addContent(new Entity(&masterName&)));//输出文档//第一个参数是缩进字符串,这里是4个空格。//第二个参数是true,表示需要换行。XMLOutputter printDoc = new XMLOutputter(& &, true);printDoc.output(doc, new FileOutputStream(&StuInfo.xml&));4.JAXB (Java And XML Binding)JAXB 是以SUN为主的一些公司公布的。JAXB将schema(或者DTD)映射为java对象(.java文件),然后使用这些java对象来解析xml文件。需要使用之前生成java文件,因而要有固定的schema,无法处理动态的xml文件。首先使用xjc命令,生成java文件xjc[-options ...](生成的文件较多)Java代码JAXBContext jc = JAXBContext.newInstance(“packageName&);Unmarshaller unmarshaller = jc.createUnmarshaller();Collection collection= (Collection)unmarshaller.unmarshal(new File( &books.xml&));CollectionType.BooksType booksType =collection.getBooks();List bookList = booksType.getBook();for( … ){test.jaxb.BookType book =(test.jaxb.BookType) bookList.get(i);System.out.println(&Book Name: & + book.getName().trim());System.out.println(&Book ISBN: & +book.getISBN());}补充另一种方法: 据悉dom4j在xml解析方面是性能最好的,hibernate等框架都使用它作为解析的工具。 要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要加入包jaxen-1.1-beta-7.jar写了简单的dom4j的使用的demo,以备回忆,有些是dom4j的文挡里例子改编的 使用dom4j解析下面的xml文件。 Xml代码&?xml version=&1.0& encoding=&GB2312&?&&?xml-stylesheet type=&text/xsl& href=&students.xsl&?&&students&&student sn=&01&&&name&张三&/name&&age&18&/age&&/student&&student sn=&02&&&name&李四&/name&&age&20&/age&&/student&&/students&Parse.java Java代码import java.io.Fimport org.dom4j.Aimport org.dom4j.Dimport org.dom4j.DocumentEimport org.dom4j.Eimport org.dom4j.ProcessingIimport org.dom4j.VisitorSimport org.dom4j.io.SAXRpublic class Parse {public static void main(String[] args) {SAXReader reader = new SAXReader();File file = new File(&src/students.xml&);try {Document doc = reader.read(file);doc.accept(new MyVistor());} catch (DocumentException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static class MyVistor extends VisitorSupport {public void visit(Attribute node) {System.out.println(&Attibute:---& + node.getName() + &=&+ node.getValue());}public void visit(Element node) {if (node.isTextOnly()) {System.out.println(&Element:---& + node.getName() + &=&+ node.getText());}else{System.out.println(&--------& + node.getName() + &-------&);}}@Overridepublic void visit(ProcessingInstruction node) {System.out.println(&PI:&+node.getTarget()+& &+node.getText());}}}使用dom4j来将属性写入xml Java代码import java.io.FileWimport java.io.IOEimport org.dom4j.Dimport org.dom4j.DocumentHimport org.dom4j.Eimport org.dom4j.io.OutputFimport org.dom4j.io.XMLWpublic class DWriter {public static void main(String[] args) {// TODO Auto-generated method stubtry {XMLWriter writer = new XMLWriter(new FileWriter(&src/author.xml&));Document doc = createDoc();writer.write(doc);writer.close();// Pretty print the document to System.out// 设置了打印的格式,将读出到控制台的格式进行美化OutputFormat format = OutputFormat.createPrettyPrint();writer = new XMLWriter(System.out, format);writer.write(doc);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Document createDoc() {Document doc = DocumentHelper.createDocument();Element root = doc.addElement(&root&);Element author1 = root.addElement(&author&).addAttribute(&name&,&Kree&).addAttribute(&location&, &UK&).addText(&Kree Strachan&);Element author2 = root.addElement(&author&).addAttribute(&name&, &King&).addAttribute(&location&, &US&).addText(&King McWrirter&);}}使用dom4j写入到author.xml文件的内容Java代码&?xml version=&1.0& encoding=&UTF-8&?&&root&&author name=&Kree& location=&UK&&Kree Strachan&/author&&author name=&King& location=&US&&King McWrirter&/author&&/root&
相关推荐:dom4j中文乱码.cn/s/blog_3d25e30f0100cyzi.htmlorg.dom4j.io.XMLWriter xmlWriter = new org.dom4j.io.XMLWriter( new FileOutputStream(fileName));在java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXBhttp://kree.i
? ? Java中解析XML的工具很多,像JDOM,DOM4J等,但Java标准库提供的两种解析XML文档解析器是:DOM(Document Object Module)解析器 和 SAX(Simple API for XML)解析器。DOM解析器会读入整个XML文...
------分隔线----------------------------
相关阅读排行php中对xml读取的相关函数的介绍一
php中对xml读取的相关函数的介绍:
--------------------------------------------------------------------------------
对象 XML解析函数 描述 元素 xml_set_element_handler() 元素的开始和结束 字符数据 xml_set_character_data_handler() 字符数据的开始 外部实体 xml_set_external_entity_ref_handler() 外部实体出现 未解析外部实体 xml_set_unparsed_entity_decl_handler() 未解析的外部实体出现 处理指令 xml_set_processing_instruction_handler() 处理指令的出现 记法声明 xml_set_notation_decl_handler() 记法声明的出现 默认 xml_set_default_handler() 其它没有指定处理函数的事件
--------------------------------------------------------------------------------
下面就给大家举一个小小的例子用parser函数来读取xml数据:
xml文件代码如下:
这个程序的结果如下:
引用:--------------------------------------------------------------------------------
名字:张三 职位:经理名字:李四 职位:助理
&?xml version=&1.0&?&&employees&&employee&&name&张三&/name&&position age=&45&&经理&/position&&/employee&&employees&&employee&&name&李四&/name&&position age=&45&&助理&/position&&/employee&&/employees&
&?php$parser = xml_parser_create(); //创建一个parser编辑器xml_set_element_handler($parser, &startElement&, &endElement&);//设立标签触发时的相应函数 这里分别为startElement和endElenmentxml_set_character_data_handler($parser, &characterData&);//设立数据读取时的相应函数$xml_file=&1.xml&;//指定所要读取的xml文件,可以是url$filehandler = fopen($xml_file, &r&);//打开文件
while ($data = fread($filehandler, 4096)) {&&& xml_parse($parser, $data, feof($filehandler));}//每次取出4096个字节进行处理
fclose($filehandler);xml_parser_free($parser);//关闭和释放parser解析器
$name=$position=function startElement($parser_instance, $element_name, $attrs)&&&&&&& //起始标签事件的函数&{&& global $name,$ &&& if($element_name==&NAME&)&& {&& $name=&& $position=&& echo &名字:&;& }& if($element_name==&POSITION&)&& {$name=&& $position=&& echo &职位:&;& }}
function characterData($parser_instance, $xml_data)&&&&&&&&&&&&&&&&& //读取数据时的函数 {&& global $name,$&& if($position)&&& echo $xml_data.&&br&&;&&& if($name)&&&& echo $xml_data.&&br&&;}
function endElement($parser_instance, $element_name)&&&&&&&&&&&&&&&& //结束标签事件的函数{&global $name,$&$name=$position=& }
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
我们今天的主题不是论述XML的好处,而是讨论在C#中如何使用XML.下面我们来了解一下使用程序访问XML的一些基础理论知识. 访问的两种模型: 在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使用DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询,但是,DOM的缺点在于它需要一 ...
在介绍Flex中操作XML之前,首先简单介绍下XML中的基本术语.
元素:XML中拥有开始标签和结束标签的这一块称为“元素”
节点:把XML元素与文本结合起来统称为节点
根节点:位于整个XML文当顶端的节点
文本节点:包含文本的节点
属性:元素的组成部分,以键/值形式放在元素标签内
用一个例子来说明 &ro ...
在我的上一篇文章&C#中使用XML——读取XML&中和大家讨论了如何使用.NET Framework中提供的类在C#中读取XML以及读取的一些相关概念,那么今天就说一说如何在C#中编写XML文档,起初我觉得用编程的方式去编写XML简直就是自讨苦吃,后来想想还是觉得挺有用的,我想Microsoft那班家伙能编出这些类来应该不是仅仅为了向比尔 ...
XMLFlexAppleAdobeActionScript.flex 操作xml 实现增删改查 12:38转载自 zhao_gw最终编辑 zhao_gw详细介绍Flex中操作XML(上)日 星期三 12:05一 在介绍Flex中操作XML之前,首先简单介绍下XML中的基本术语.
元素:XML中拥有开始标签和结束标签 ...
SAX解析XML文件就比DOM方便了许多,而且他支持解析大文件量的XML文件,但是他不能对XML文件中的单独节点进行操作,只能一次性的将内容全部读出来,而且还可以将XML中的属性读取出来,下面介绍SAX解析XML文件的具体步骤. 1.需要构建SAX解析树,既是自己要写个类继承DefaultHandler这个类,并且重写里面的 public void star ...
本文完全来源于http://blog.csdn.net/tiemufeng1122/article/details/6723764,仅作个人学习之用. XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内容的技术 ...
SAX是一种事件驱动的流式XML文件处理方式,区别与DOM方式的是不需要在内存中建一棵DOM树,而是根据读取XML时遇到的标签事件来顺序处理,因此具有速度快,内存占用上的优点.SAX往往是大容量XML文件处理的首选方法,SAX读取XML相对比较简单,但是写XML就稍微比DOM方式复杂一些,网上的例子也不够全面和详细,刚好在工作中用到了XML读取和写出XML, ...
C#中使用XML指南之读取XML
访问的两种模型:
在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使用DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询,但是,DOM的缺点在于它需要一次性的加载整个文档到内存中,对于大型的文档,这会造成资源问题.流模型很好的解决了 ...一、邂逅XML
文件种类是丰富多彩的,XML作为众多文件类型的一种,经常被用于数据存储和传输。所以XML在现今应用程序中是非常流行的。本文主要讲Java解析和生成XML。用于不同平台、不同设备间的数据共享通信。
XML文件的表现:以&.xml&为文件扩展名的文件;
   存储结构:树形结构;
节点名称区分大小写。
1、&book id="1"&&/book& id为属性, &book&&id&1&/id&&/book& id为节点2、xml文件开头要加上版本信息和编码方式&?xml version="1.0" encoding="UTF-8"?&
? 为什么要使用XML?
思考1:不同应用程序之间的通信?
思考2:不同平台间的通信?
思考3:不同平台间的数据共享?
答案就是我们要学习的XML文件。我们可以使用相同的xml把不同的文件联系起来
二、应用 DOM 方式解析 XML
?&在Java程序中如何获取XML文件的内容
解析的目的:获取节点名、节点值、属性名、属性值;
四种解析方式:DOM、SAX、DOM4J、JDOM&
DOM、SAX :java 官方方式,不需要下载jar包DOM4J、JDOM :第三方,需要网上下载jar包
示例:解析XML文件,目标是解析XML文件后,Java程序能够得到xml文件的所有数据
思考:如何在Java程序中保留xml数据的结构?
如何保留节点之间的层级关系?
注意常用的节点类型:
&下面介绍DOM方式解析XML:
&功能说明:
代码示例:
1 package com.study.
3 import java.io.IOE
5 import javax.xml.parsers.DocumentB
6 import javax.xml.parsers.DocumentBuilderF
7 import javax.xml.parsers.ParserConfigurationE
9 import org.w3c.dom.D
10 import org.w3c.dom.NamedNodeM
11 import org.w3c.dom.N
12 import org.w3c.dom.NodeL
13 import org.xml.sax.SAXE
* DOM方式解析xml
18 public class DOMTest {
public static void main(String[] args) {
//1、创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//2、创建一个DocumentBuilder的对象
//创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
//3、通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
/*注意导入Document对象时,要导入org.w3c.dom.Document包下的*/
Document document = db.parse("books.xml");//传入文件名可以是相对路径也可以是绝对路径
//获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
//通过nodelist的getLength()方法可以获取bookList的长度
System.out.println("一共有" + bookList.getLength() + "本书");
//遍历每一个book节点
for (int i = 0; i & bookList.getLength(); i++) {
System.out.println("=================下面开始遍历第" + (i + 1) + "本书的内容=================");
//?未知节点属性的个数和属性名时:
//通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
Node book = bookList.item(i);
//获取book节点的所有属性集合
NamedNodeMap attrs = book.getAttributes();
System.out.println("第 " + (i + 1) + "本书共有" + attrs.getLength() + "个属性");
//遍历book的属性
for (int j = 0; j & attrs.getLength(); j++) {
//通过item(index)方法获取book节点的某一个属性
Node attr = attrs.item(j);
//获取属性名
System.out.print("属性名:" + attr.getNodeName());
//获取属性值
System.out.println("--属性值" + attr.getNodeValue());
//?已知book节点有且只有1个id属性:
//前提:已经知道book节点有且只能有1个id属性
//将book节点进行强制类型转换,转换成Element类型
Element book1 = (Element) bookList.item(i);
//通过getAttribute("id")方法获取属性值
String attrValue = book1.getAttribute("id");
System.out.println("id属性的属性值为" + attrValue);
//解析book节点的子节点
NodeList childNodes = book.getChildNodes();
//遍历childNodes获取每个节点的节点名和节点值
System.out.println("第" + (i+1) + "本书共有" + childNodes.getLength() + "个子节点");
for (int k = 0; k & childNodes.getLength(); k++) {
//区分出text类型的node以及element类型的node
if(childNodes.item(k).getNodeType() == Node.ELEMENT_NODE){
//获取了element类型节点的节点名
System.out.print("第" + (k + 1) + "个节点的节点名:" + childNodes.item(k).getNodeName());
//获取了element类型节点的节点值
System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());
System.out.println("--节点值是:" + childNodes.item(k).getTextContent());
System.out.println("======================结束遍历第" + (i + 1) + "本书的内容=================");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
&三、应用 SAX 方式解析 XML
SAX是SIMPLE API FOR XML的缩写,与DOM比较而言,SAX是一种轻量型的方法。
Dom解析会将整个xml文件加载到内存中,然后再逐个解析Sax解析是通过Handler处理类逐个依次解析每个节点
在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个NODE对象。当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当费时费力。特别是其对于内存的需求,也将是成倍的增长,以至于在某些应用中使用DOM是一件很不划算的事。这时候,一个较好的替代解决方法就是SAX。
SAX在概念上与DOM完全不同。首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。在XMLReader接受XML文档,在读入XML文档的过程中就进行解析,也就是说读入文档的过程和解析的过程是同时进行的,这和DOM区别很大。
代码示例:Book实体类
1 package com.study.saxtest.
* 用Book实体类代表XML文件中的"&book&...&/book&"中整个元素
* 在遇到&book&标签,证明我们要存储新的book时需要创建Book对象
7 public class Book {
public String getId() {
public void setId(String id) {
public String getName() {
public void setName(String name) {
this.name =
public String getAuthor() {
public void setAuthor(String author) {
this.author =
public String getYear() {
public void setYear(String year) {
this.year =
public String getPrice() {
public void setPrice(String price) {
this.price =
public String getLanguage() {
public void setLanguage(String language) {
this.language =
SAXParserHandler类:
1 package com.study.saxtest.
3 import java.util.ArrayL
5 import org.xml.sax.A
6 import org.xml.sax.SAXE
7 import org.xml.sax.helpers.DefaultH
9 import com.study.saxtest.entity.B
11 public class SAXParserHandler extends DefaultHandler{
/*注意DefaultHandler是org.xml.sax.helpers包下的*/
int bookIndex = 0;//设置全局变量,用来记录是第几本书
String value = null;
Book book = null;
private ArrayList&Book& bookList = new ArrayList&Book&();//保存book对象
public ArrayList&Book& getBookList() {
return bookL
* 用来标识解析开始
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("SAX解析开始");
* 用来标识解析结束
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("SAX解析结束");
* 用来遍历xml文件的开始标签
* 解析xml元素
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
//调用DefaultHandler类的startElement方法
super.startElement(uri, localName, qName, attributes);
if (qName.equals("book")) {
bookIndex++;
//创建一个book对象
/*Book*/ book = new Book();
//开始解析book元素的属性
System.out.println("======================开始遍历第"+bookIndex+"本书的内容=================");
/* //?已知节点的属性名时:比如已知id属性,根据属性名称获取属性值
String value = attributes.getValue("id");
System.out.print("book的属性值是:"+value);*/
//?未知节点的属性名时,获取属性名和属性值
int num=attributes.getLength();
for(int i=0;i&i++){
System.out.print("book元素的第"+(i+1)+"个属性名是:"+attributes.getQName(i));
System.out.println("---属性值是:"+attributes.getValue(i));
if (attributes.getQName(i).equals("id")) {//往book对象中塞值
book.setId(attributes.getValue(i));
}else if (!qName.equals("book") && !qName.equals("bookstore")) {
System.out.print("节点名是:" + qName + "---");//此时qName获取的是节点名(标签)
* 用来遍历xml文件的结束标签
public void endElement(String uri, String localName, String qName) throws SAXException {
//调用DefaultHandler类的endElement方法
super.endElement(uri, localName, qName);
//判断是否针对一本书已经遍历结束
if (qName.equals("book")) {
bookList.add(book);//在清空book对象之前先保存
book = null;//把book清空,方便解析下一个book节点
System.out.println("======================结束遍历第"+bookIndex+"本书的内容=================");
}else if (qName.equals("name")) {
book.setName(value);
else if (qName.equals("author")) {
book.setAuthor(value);
else if (qName.equals("year")) {
book.setYear(value);
else if (qName.equals("price")) {
book.setPrice(value);
else if (qName.equals("language")) {
book.setLanguage(value);
* 获取文本
* 重写charaters()方法时,
* String(byte[] bytes,int offset,int length)的构造方法进行数组的传递
* 去除解析时多余空格
public void characters(char[] ch, int start, int length)throws SAXException {
* ch 代表节点中的所有内容,即每次遇到一个标签调用characters方法时,数组ch实际都是整个XML文档的内容
* 如何每次去调用characters方法时我们都可以获取不同的节点属性?这时就必须结合start(开始节点)和length(长度)
super.characters(ch, start, length);
/*String */value = new String(ch, start, length);//value获取的是文本(开始和结束标签之间的文本)
System.out.println(value);//输出时会多出两个空格,是因为xml文件中空格与换行字符被看成为一个文本节点
if(!value.trim().equals("")){//如果value去掉空格后不是空字符串
System.out.println("节点值是:" + value);
* qName获取的是节点名(标签)
* value获取的是文本(开始和结束标签之间的文本)
* 思考:qName和value分别在两个方法中,如何将这两个方法中的参数整合到一起?
* 分析:要在两个方法中用同一个变量,就设置成全局变量,可以赋初值为null。
可以把characters()方法中的value作成一个全局变量
* 然后在endElement()方法中对book对象进行塞值。记得要把Book对象设置为全局变量,变量共享
测试类:SAXTest
1 package com.study.saxtest.
3 import java.io.IOE
5 import javax.xml.parsers.ParserConfigurationE
6 import javax.xml.parsers.SAXP
7 import javax.xml.parsers.SAXParserF
9 import org.xml.sax.SAXE
11 import com.study.saxtest.entity.B
12 import com.study.saxtest.handler.SAXParserH
* sax方式解析XML
17 public class SAXTest {
public static void main(String[] args) {
//1.获取一个SAXParserFactory的实例对象
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.通过factory的newSAXParser()方法获取一个SAXParser类的对象。
SAXParser parser = factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler = new SAXParserHandler();
parser.parse("books.xml", handler);
System.out.println("~~~~~共有"+handler.getBookList().size()+"本书");
for (Book book : handler.getBookList()) {
System.out.println(book.getId());
System.out.println(book.getName());
System.out.println(book.getAuthor());
System.out.println(book.getYear());
System.out.println(book.getPrice());
System.out.println(book.getLanguage());
System.out.println("----finish----");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
&运行结果:
SAX解析开始
======================开始遍历第1本书的内容=================
book元素的第1个属性名是:id---属性值是:1
节点名是:name---节点值是:冰与火之歌
节点名是:author---节点值是:乔治马丁
节点名是:year---节点值是:2014
节点名是:price---节点值是:89
======================结束遍历第1本书的内容=================
======================开始遍历第2本书的内容=================
book元素的第1个属性名是:id---属性值是:2
节点名是:name---节点值是:安徒生童话
节点名是:year---节点值是:2004
节点名是:price---节点值是:77
节点名是:language---节点值是:English
======================结束遍历第2本书的内容=================
SAX解析结束
~~~~~共有2本书
冰与火之歌
----finish----
安徒生童话
----finish----
&四、应用 DOM4J 及 JDOM 方式解析 XML
&#&JDOM 方式解析 XML
  JDOM 开始解析前的准备工作:
  JDOM是第三方提供的解析XML方法,需要jdom-2.0.5.jar包
&示例代码:
1 package com.study.jdomtest1.
3 import java.io.FileInputS
4 import java.io.FileNotFoundE
5 import java.io.IOE
6 import java.io.InputS
7 import java.io.InputStreamR
8 import java.util.ArrayL
9 import java.util.L
11 import org.jdom2.A
12 import org.jdom2.D
13 import org.jdom2.E
14 import org.jdom2.JDOME
15 import org.jdom2.input.SAXB
17 import com.study.jdomtest1.entity.B
JDOM 解析XML
22 public class JDOMTest {
private static ArrayList&Book& booksList = new ArrayList&Book&();
public static void main(String[] args) {
// 进行对books.xml文件的JDOM解析
//?准备工作
// 1.创建一个SAXBuilder的对象
SAXBuilder saxBuilder = new SAXBuilder();//注意SAXBuilder是org.jdom2.input包下的
// 2.创建一个输入流,将xml文件加载到输入流中
in=new FileInputStream("books.xml");//如果将xml文件放在src/res包下,此时应该输入&src/res/books.xml&
InputStreamReader isr = new InputStreamReader(in, "UTF-8");//使用包装流InputStreamReader进行读取编码的指定,防止乱码
// 3.通过saxBuilder的build方法,将输入流加载到saxBuilder中
Document document = saxBuilder.build(isr);
// 4.通过document对象获取xml文件的根节点
Element rootElement = document.getRootElement();
// 5.获取根节点下的子节点的List集合
List&Element& bookList = rootElement.getChildren();
//? 继续解析,采用for循环对bookList进行遍历
for (Element book : bookList) {
Book bookEntity = new Book();
System.out.println("======开始解析第" + (bookList.indexOf(book) + 1) + "书======");//indexOf()返回的是index的位置,是从0开始
// 解析book的属性集合
List&Attribute& attrList = book.getAttributes();//适用于未知属性情况下
/*//知道节点下属性名称时,获取节点值
book.getAttributeValue("id");*/
// 遍历attrList(针对不清楚book节点下属性的名字及数量)
for (Attribute attr : attrList) {
/**注:JDom中,Attribute的getName和getValue方法获取到的都是实际的名称和值,
* 不会出现SAX和DOM中的空格和换行的情况*/
// 获取属性名
String attrName = attr.getName();
// 获取属性值
String attrValue = attr.getValue();
System.out.println("属性名:" + attrName + "----属性值:" + attrValue);
if (attrName.equals("id")) {
bookEntity.setId(attrValue);
//?对book节点的子节点的节点名以及节点值的遍历
List&Element& bookChilds = book.getChildren();
for (Element child : bookChilds) {
System.out.println("节点名:" + child.getName() + "----节点值:" + child.getValue());
if (child.getName().equals("name")) {
bookEntity.setName(child.getValue());
else if (child.getName().equals("author")) {
bookEntity.setAuthor(child.getValue());
else if (child.getName().equals("year")) {
bookEntity.setYear(child.getValue());
else if (child.getName().equals("price")) {
bookEntity.setPrice(child.getValue());
else if (child.getName().equals("language")) {
bookEntity.setLanguage(child.getValue());
System.out.println("======结束解析第" + (bookList.indexOf(book) + 1) + "书======");
booksList.add(bookEntity);
bookEntity = null;
//测试数据
System.out.println(booksList.size());
System.out.println(booksList.get(0).getId());
System.out.println(booksList.get(0).getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
?关于 JDOM 使用过程中 JAR 包的引用 :
方式1:通过右击项目--&build path--&add external archives...--&然后选择本地文件的jar包 这种方式并不能将jar包真正导入到项目源码中,当把项目导出放在另外的机器上,这个jar包并不会随着project一同被导出。
方式2:项目根目录下新建lib文件夹&&复制、粘帖jar包&&右击jar包选择&build path构建路径&&&&add to build path添加至构建路径&即可
&&#&DOM4J&方式解析 XML&
  DOM4J&是第三方提供的解析XML方法,需要dom4j-1.6.1.jar包
1 package com.study.dom4
3 import java.io.F
4 import java.util.I
5 import java.util.L
7 import org.dom4j.A
8 import org.dom4j.D
9 import org.dom4j.DocumentE
10 import org.dom4j.E
11 import org.dom4j.io.SAXR
* DOM4J 方式解析XML
16 public class DOM4JTest {
public static void main(String[] args) {
// 解析books.xml文件
// 创建SAXReader的对象reader
SAXReader reader = new SAXReader();
// 通过reader对象的read方法加载books.xml文件,获取docuemnt对象。
Document document = reader.read(new File("books.xml"));
// 通过document对象获取根节点bookstore
Element bookStore = document.getRootElement();
// 通过element对象的elementIterator方法获取迭代器
Iterator it = bookStore.elementIterator();
// 遍历迭代器,获取根节点中的信息(书籍)
while (it.hasNext()) {
System.out.println("=====开始遍历某一本书=====");
Element book = (Element) it.next();
// 获取book的属性名以及 属性值
List&Attribute& bookAttrs = book.attributes();
for (Attribute attr : bookAttrs) {
System.out.println("属性名:" + attr.getName() + "--属性值:" + attr.getValue());
//解析子节点的信息
Iterator itt = book.elementIterator();
while (itt.hasNext()) {
Element bookChild = (Element) itt.next();
System.out.println("节点名:" + bookChild.getName() + "--节点值:" + bookChild.getStringValue());
System.out.println("=====结束遍历某一本书=====");
} catch (DocumentException e) {
e.printStackTrace();
五、四种解析方式比较分析
基础方法:DOM(平台无关的官方解析方式)、SAX(基于事件驱动的解析方式)扩展方法:JDOM、DOM4J(在基础的方法上扩展出的,只有在java中能够使用的解析方法)
##解析速度的分析&
XML四种解析方式性能测试:SAX&DOM&DOM4J&JDOM
JUnit是Java提供的一种进行单元测试的自动化工具。测试方法可以写在任意类中的任意位置。使用JUnit可以没有main()入口进行测试。DOM4J在灵活性和对复杂xml的支持上都要强于DOMDOM4J的应用范围非常的广,例如在三大框架的Hibernate中是使用DOM4J的方式解析文件的。DOM是w3c组织提供的一个官方解析方式,在一定程度上是有所应用的。当XML文件比较大的时候,会发现DOM4J比较好用1.JUnit:Java提供的单元测试;@Test注解;采用JUnit不需要程序入口main方法2.性能测试结果:几kB的xml文件;建议使用DOM4J解析   DOM-33ms   SAX-6ms   JDOM-69ms   DOM4J-45ms 工程右键build path --Add library--JUnit单元测试 --version:JUnit4   DOM:33,SAX:6   JDOM:69;DOM4J:45   DOM 有可能溢出 多使用DOM4J
阅读(...) 评论()

我要回帖

更多关于 sax写入换行 的文章

 

随机推荐