Java Sax解析xml

1.   Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode。如下面的这段book.xml

Xml代码  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <books>
  3. <book id="12">
  4. <name>thinking in java</name>
  5. <price>85.5</price>
  6. </book>
  7. <book id="15">
  8. <name>Spring in Action</name>
  9. <price>39.0</price>
  10. </book>
  11. </books>

其中,像<books>、<book>这种节点就属于ElementNode,而thinking in java、85.5这种就属于TextNode。

下面结合一张图来详细讲解Sax解析。

xml文件被Sax解析器载入,由于Sax解析是按照xml文件的顺序来解析,当读入<?xml.....>时,会调用startDocument()方法,当读入<books>的时候,由于它是个ElementNode,所以会调用startElement(String uri, String localName, String qName, Attributes attributes) 方法,其中第二个参数就是节点的名称,注意:由于有些环境不一样,有时候第二个参数有可能为空,所以可以使用第三个参数,因此在解析前,先调用一下看哪个参数能用,第4个参数是这个节点的属性。这里我们不需要这个节点,所以从<book>这个节点开始,也就是图中1的位置,当读入时,调用startElement(....)方法,由于只有一个属性id,可以通过attributes.getValue(0)来得到,然后在图中标明2的地方会调用characters(char[] ch, int start, int length)方法,不要以为那里是空白,Sax解析器可不那么认为,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<name>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name,是再取值,才能取到thinking in java。具体见代码:SaxParseService.java

Java代码  

  1. import java.io.InputStream;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.xml.parsers.SAXParser;
  5. import javax.xml.parsers.SAXParserFactory;
  6. import org.xml.sax.Attributes;
  7. import org.xml.sax.SAXException;
  8. import org.xml.sax.helpers.DefaultHandler;
  9. import com.xtlh.cn.entity.Book;
  10. public class SaxParseService extends DefaultHandler{
  11. private List<Book> books = null;
  12. private Book book = null;
  13. private String preTag = null;//作用是记录解析时的上一个节点名称
  14. public List<Book> getBooks(InputStream xmlStream) throws Exception{
  15. SAXParserFactory factory = SAXParserFactory.newInstance();
  16. SAXParser parser = factory.newSAXParser();
  17. SaxParseService handler = new SaxParseService();
  18. parser.parse(xmlStream, handler);
  19. return handler.getBooks();
  20. }
  21. public List<Book> getBooks(){
  22. return books;
  23. }
  24. @Override
  25. public void startDocument() throws SAXException {
  26. books = new ArrayList<Book>();
  27. }
  28. @Override
  29. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  30. if("book".equals(qName)){
  31. book = new Book();
  32. book.setId(Integer.parseInt(attributes.getValue(0)));
  33. }
  34. preTag = qName;//将正在解析的节点名称赋给preTag
  35. }
  36. @Override
  37. public void endElement(String uri, String localName, String qName)
  38. throws SAXException {
  39. if("book".equals(qName)){
  40. books.add(book);
  41. book = null;
  42. }
  43. preTag = null;/**当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
  44. ,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
  45. 中标记4的位置时,会执行characters(char[] ch, int start, int length)这个方法,而characters(....)方
  46. 法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。*/
  47. }
  48. @Override
  49. public void characters(char[] ch, int start, int length) throws SAXException {
  50. if(preTag!=null){
  51. String content = new String(ch,start,length);
  52. if("name".equals(preTag)){
  53. book.setName(content);
  54. }else if("price".equals(preTag)){
  55. book.setPrice(Float.parseFloat(content));
  56. }
  57. }
  58. }
  59. }

Book.java如下:主要是用来组装数据

Java代码  

  1. public class Book {
  2. private int id;
  3. private String name;
  4. private float price;
  5. public int getId() {
  6. return id;
  7. }
  8. public void setId(int id) {
  9. this.id = id;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public float getPrice() {
  18. return price;
  19. }
  20. public void setPrice(float price) {
  21. this.price = price;
  22. }
  23. @Override
  24. public String toString(){
  25. return this.id+":"+this.name+":"+this.price;
  26. }
  27. }

测试是用的单元测试,测试代码如下:ParseTest

Java代码  

  1. import java.io.InputStream;
  2. import java.util.List;
  3. import junit.framework.TestCase;
  4. import com.xtlh.cn.demo.DomParseService;
  5. import com.xtlh.cn.demo.SaxParseService;
  6. import com.xtlh.cn.entity.Book;
  7. public class ParseTest extends TestCase{
  8. public void testSAX() throws Throwable{
  9. SaxParseService sax = new SaxParseService();
  10. InputStream input = this.getClass().getClassLoader().getResourceAsStream("book.xml");
  11. List<Book> books = sax.getBooks(input);
  12. for(Book book : books){
  13. System.out.println(book.toString());
  14. }
  15. }
  16. }

在用Sax解析的时候最需要重视的一点就是不要把那些<节点>之间的空白忽略就好!

时间: 2024-09-30 04:51:14

Java Sax解析xml的相关文章

JAVA SAX解析XML文件

[代码] [Java]代码view sourceprint?001package SAXparse;002 003 004import java.io.FileInputStream;005import java.lang.reflect.Array;006import java.lang.reflect.InvocationTargetException;007import java.lang.reflect.Method;008import java.text.ParseException;

JAVA SAX解析XML字符串实例

Demo代码如下: package com.wenqi.demo; import java.io.IOException; import java.io.StringReader; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.xml.sax.I

Java用SAX解析XML

Myhandler package com.heli.xml.sax; /**  * 用SAX解析XML的Handler  */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.hel

SAX解析XML

SAX 事件处理(事件驱动),不需要载入整个文档,流机制读取,分析XML文档 startDocument startElement character endElement endDocument 当sax扫描到文档时就调用startDocument函数,sax扫描到文档结束符时就调用endDocument函数,也就是说当sax扫描到哪个节点时就会调用相应的函数,同时还会携带节点的属性值. 当它扫描到节点内容值时就会调用character函数 Sax主要是用来对xml文件遍历,解析,不提供修改.

6. SAX解析XML

SAX解析: SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分: 解析器和事件处理器 : 1. 解析器可以使用SAXP的API创建,创建出SAX解析器后, 就可以指定解析器去解析某个XML文档. 解析器采用SAX方式在解析某个XML文档时, 它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法, 解析器在调用事件处理器的方法时, 会把当前解析到的xml文件内容作为方法的参数传递给事件处理器. 2. 事件处理器由程序员编写,程序员通过事件处理器

XML学习笔记(二):使用 DOM和SAX 解析XML :

一.XML解析的简介 1.一般来说xml解析的方式有两种,Dom与SAX,且各有优缺点.pull是第三种方法见:pull解析XML 1)DOM:dom对象树 ①.整个XML放入内存,转换为Document对象: ②.每个元素,转换成Element对象 ③.文本,转换成Text对象 ④.属性,转换成Attribute对象 优缺点:元素的CRUD比较简单,但是内存消耗大,大的xml文档不适合. 补充:内存不足时,可以修改参数,调整JVM的内存大小 1.java.lang.OutOfMemoryErr

SAX解析XML文件

SAX是Simple API for XML的缩写,它并不是由W3C官方所提出的标准.SAX是一种轻量型的方法,不像DOM解析时,把XML文档全部载入内存中,在PC上操作,Dom还有 优势,但在手机中端上则无优势,因为手机内存和硬件都比不上PC强.使用 SAX 是比较安全的,并且 Android 提供了一种传统的 SAX 使用方法,以及一个便捷的 SAX 包装器.SAX采用基于事件驱动的处理方式,它将XML文档转换成一系列的事件,由单独的事件处理器来决定如何处理. 在SAX接口中,事件源是org

android学习二十二(使用SAX解析xml)

上一篇博客是使用Pull解析xml文件的,Pull解析方式虽然非常好用,但它并不是我们唯一的选择.SAX解析也是一种特别常用的XML解析方式,虽然它的用法比Pull解析复杂,但在语义方面会更加的清楚. 通常情况下我们都会新建一个类继承自DefaultHandler,并重写父类的五个方法,如下所示: package com.jack.networktest; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import

Python:使用基于事件驱动的SAX解析XML

SAX的特点: 是基于事件的 API 在一个比 DOM 低的级别上操作 为您提供比 DOM 更多的控制 几乎总是比 DOM 更有效率 但不幸的是,需要比 DOM 更多的工作 基于对象和基于事件的接口 您可能已经知道语法分析器有两类接口 - 基于对象的(如:DOM)和基于事件(如:SAX)的接口. DOM是基于对象的语法分析器的标准 API. 作为基于对象的接口,DOM 通过在内存中显示地构建对象树来与应用程序通信.对象树是 XML 文件中元素树的精确映射. DOM 易于学习和使用,因为它与基本