首先我们先将xml何为格式好何为格式不好讲清楚
先上格式好的图
在一个就是格式不好的图
我们可以看出来,格式好的与格式不好的之间的差别在于, 不好的多了很多 \n \t 这样的换行符之类的东西。
那么我们上代码
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 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,length) ;
....
book.setName(temp);
这两行代码被执行了多次,
之前得到的数据被冲掉了,所以会出现数据拿不到的情况,
结果如图
书名: thinking in java 结果值被冲掉了
那么现在我们来看正确的写法,对,就是使用StringBuffer类,利用其append方法,无论这个character方法被执行了多少次,反正是往字符缓冲中append字符,数据不会被冲掉。
在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,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,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 { } }
结果如下