SAX解析XML文档的时候在characters方法中解析有的时候xml文档格式凌乱的时候拿不到数据

首先我们先将xml何为格式好何为格式不好讲清楚


先上格式好的图

在一个就是格式不好的图

我们可以看出来,格式好的与格式不好的之间的差别在于, 不好的多了很多 \n \t 这样的换行符之类的东西。

在格式不好的情况下  characters方法会调用多次。

那么我们上代码

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParseService extends DefaultHandler
{
	
	private List<Book> books = null;
	private Book book = null;
	private String preTag = null;
	
	

	public List<Book> getBooks(InputStream xmlStream) throws Exception
	{
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		SaxParseService handler = new SaxParseService();
		parser.parse(xmlStream, handler);
		return handler.getBooks();
	}

	public List<Book> getBooks()
	{
		return books;
	}

	@Override
	public void startDocument() throws SAXException
	{
		books = new ArrayList<Book>();
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
	{
		
		if ("book".equals(qName))
		{
			book = new Book();
			book.setId(Integer.parseInt(attributes.getValue(0)));
		}
		preTag = qName;
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException
	{
		if ("book".equals(qName))
		{
			books.add(book);
			book = null;
		}
		preTag = null;
		
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException
	{
		
		
		if (preTag != null)
		{
			String temp = new String(ch,start,length);
			
//			log.info(temp.trim().equals(""));
			temp = temp.trim();
			
			
			
			if ("name".equals(preTag))
			{
				book.setName(temp);
			}
			else if ("price".equals(preTag))
			{
				book.setPrice(Float.parseFloat(temp));
			}
		}
		
	}
	
	@Override
	public void endDocument() throws SAXException
	{
	}

}

这种写法呢,在格式好的情况下,数据可以被正常拿到,单是在 格式不好的情况下 充满了大量的 \n \t 导致character方法被执行了多次。

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

....

book.setName(temp);

这两行代码被执行了多次,

之前得到的数据被冲掉了,所以会出现数据拿不到的情况,

结果如图

书名: thinking in java 结果值被冲掉了

那么现在我们来看正确的写法,对,就是使用StringBuffer类,利用其append方法,无论这个character方法被执行了多少次,反正是往字符缓冲中append字符,数据不会被冲掉。


在原来代码的基础上添加成员变量StringBuffer

在startElement方法中 new 出来其一个对象即可。

最后在character方法中 append得到的数据。

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParseService extends DefaultHandler
{
	
	private List<Book> books = null;
	private Book book = null;
	private String preTag = null;
	
	private StringBuffer sb ;
	

	public List<Book> getBooks(InputStream xmlStream) throws Exception
	{
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		SaxParseService handler = new SaxParseService();
		parser.parse(xmlStream, handler);
		return handler.getBooks();
	}

	public List<Book> getBooks()
	{
		return books;
	}

	@Override
	public void startDocument() throws SAXException
	{
		books = new ArrayList<Book>();
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
	{
		
		sb = new StringBuffer();
		
		if ("book".equals(qName))
		{
			book = new Book();
			book.setId(Integer.parseInt(attributes.getValue(0)));
		}
		preTag = qName;
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException
	{
		if ("book".equals(qName))
		{
			books.add(book);
			book = null;
		}
		preTag = null;
		
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException
	{
		
		
		if (preTag != null)
		{
			String temp = new String(ch,start,length);
			
//			log.info(temp.trim().equals(""));
			temp = temp.trim();
			
			
			sb.append(temp);
			
			if ("name".equals(preTag))
			{
				book.setName(sb.toString());
			}
			else if ("price".equals(preTag))
			{
				book.setPrice(Float.parseFloat(sb.toString()));
			}
		}
		
	}
	
	@Override
	public void endDocument() throws SAXException
	{
	}

}




结果如下



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值