您的位置:首页 > 编程语言 > Java开发

Java使用SAM解析XML

2015-12-05 22:42 441 查看
上一篇文章中讲述了如何使用DOM解析XML,这篇文章讲一下使用SAM(Simple API for XML)解析XML.

XML文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<name>java入门</name>
<price>35.9</price>
</book>
<book id="2">
<name>java精通</name>
<price>89.6</price>
</book>
</books>


创建三个类

Book.java

public class Book {
private int id;
private String name;
private float price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString(){
return "Id is :"+this.id+"; Name is:"+this.name+"; Price is:"+this.price;
}
}


SAXTool.java

public class SAXTool {

public SAXTool() {
// TODO Auto-generated constructor stub
}
public List <Book> getBookList(InputStream xmlStream) throws Exception {
// TODO Auto-generated constructor stub
//获取SAXFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//通过factory获取SAXParser
SAXParser parser = factory.newSAXParser();
//实例化一个解析工具
SAXUtil handler = new SAXUtil();
//解析文件
/*SAX解析是边读边解析,所以读到一个element要素
*就回调handler中重写的相关方法*/
parser.parse(xmlStream, handler);
return handler.getBookList();
}

}


SAXUtil.java

public class SAXUtil extends DefaultHandler {

private List<Book> booklist = null;
private Book book;
private String preTag = null;// 作用是记录解析时的上一个节点名称

public SAXUtil() {
// TODO Auto-generated constructor stub
}

public List<Book> getBookList(){
return booklist;
}

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

/**
* 收到一个元素开始的通知
* Receive notification of the start of an element.
*
* <p>
* By default, do nothing. Application writers may override this method in a
* subclass to take specific actions at the start of each element (such as
* allocating a new tree node or writing output to a file).
* </p>
*
* @param uri
*            The Namespace URI, or the empty string if the element has no
*            Namespace URI or if Namespace processing is not being
*            performed.
* @param localName
*            The local name (without prefix), or the empty string if
*            Namespace processing is not being performed.
* @param qName
*            The qualified name (with prefix), or the empty string if
*            qualified names are not available.
* @param attributes
*            The attributes attached to the element. If there are no
*            attributes, it shall be an empty Attributes object.
* @exception org.xml.sax.SAXException
*                Any SAX exception, possibly wrapping another exception.
* @see org.xml.sax.ContentHandler#startElement
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// no op
if ("book".equals(qName)) {
book = new Book();
book.setId(Integer.parseInt(attributes.getValue(0)));
}
preTag = qName;
}

/**
* 收到一个字符数据通知
* Receive notification of character data inside an element.
*
* <p>
* By default, do nothing. Application writers may override this method to
* take specific actions for each chunk of character data (such as adding
* the data to a node or buffer, or printing it to a file).
* </p>
*
* @param ch
*            The characters.
* @param start
*            The start position in the character array.
* @param length
*            The number of characters to use from the character array.
* @exception org.xml.sax.SAXException
*                Any SAX exception, possibly wrapping another exception.
* @see org.xml.sax.ContentHandler#characters
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (preTag != null) {
String content = new String(ch, start, length);
if ("name".equals(preTag)) {
book.setName(content);
} else if ("price".equals(preTag)) {
book.setPrice(Float.parseFloat(content));
}
}
}

/**
* 收到一个元素结束的通知
* Receive notification of the end of an element.
*
* <p>
* By default, do nothing. Application writers may override this method in a
* subclass to take specific actions at the end of each element (such as
* finalising a tree node or writing output to a file).
* </p>
*
* @param uri
*            The Namespace URI, or the empty string if the element has no
*            Namespace URI or if Namespace processing is not being
*            performed.
* @param localName
*            The local name (without prefix), or the empty string if
*            Namespace processing is not being performed.
* @param qName
*            The qualified name (with prefix), or the empty string if
*            qualified names are not available.
* @exception org.xml.sax.SAXException
*                Any SAX exception, possibly wrapping another exception.
* @see org.xml.sax.ContentHandler#endElement
*/

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("book".equals(qName)) {
booklist.add(book);
book = null;
}
preTag = null;/**
* 当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
* ,如果这里不把preTag置为null,根据startElement(....)方法,
* preTag的值还是book,当文档顺序读到图 中标记4的位置时,会执行characters(char[]
* ch, int start, int length)这个方法,而characters(....)方
* 法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。
*/
}
}


在调用方法:

try {
InputStream fins = new FileInputStream("book.xml");
SAXTool Saxtool = new SAXTool();
List<Book> booklist = (List<Book>) Saxtool.getBookList(fins);
for (Book book : booklist) {
System.out.println(book.toString());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


输出结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: