XML编程研究
作者:- 来源:- 添加时间:2006-5-21 9:52:22SAX vs. DOM
DOM是基于树结构的一种接口;SAX是基于事件驱动的解析接口。
有什么区别呢?
1、SAX 可以解析任意大小的文件,而DOM 解析的文件大小则和硬件有关。DOM 需要将整个文件加载到内存,而SAX 不需要。
2、因为SAX 是不把文件加载到内存,所以不能对文档进行随机存取;而DOM 可以做到。
3、SAX 相对DOM 来说是简单易用。
4、如果要从文档的简单系列中获取信息,SAX 是最快的方法。
实例一、查查有多少本书?
题目是要查出来下面的XML 文件books.xml 里有多少本书。
<?xml version="1.0"?>
<books>
<book category="Programming">
<author>XXX1</author>
<title>Thinking in Java</title>
<price unit="RMB">60.00</price>
</book>
<book category="Programming">
<author>XXX2</author>
<title>Thinking in C++</title>
<price>56.00</price>
</book>
<book category="fiction">
<author>Slepwormzz</author>
<title>My Dirty Mind</title>
<price>8.99</price>
</book>
</books>
下面的代码使用了SUN 的JAXP 包,请在http://java.sun.com/xml/download.html 下载。
在Jbuilder4 中运行正确。
Import org.xml.sax.*;
import javax.xml.parsers.*;
import java.io.IOException;
/**
* Title: XML Study, Sample 1
* Description: Count My books.
* Copyright: Copyright ? 2001
* Company: Isolation Land.
* @author Slepworm
* @version 1.0
*/
public class BookCounter extends org.xml.sax.helpers.DefaultHandler{
private int count = 0; // 定义一个计数器
public BookCounter() {
}
// 主程序
public void countBooks() throws Exception {
// 创建一个新的JAXP 的SAXParserFactory 实例,并且配置它。在JAXP 包的例子中可以看到此种方法
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setValidating(false); // 试一下改为true
XMLReader xr = null;
try {
SAXParser sp = spf.newSAXParser();
xr = sp.getXMLReader();
} catch (Exception e) {
System.err.print(e);
System.exit(1);
}
xr.setContentHandler(this);
try {
xr.parse("/books.xml"); //进行语法分析
} catch (SAXException se) {
System.err.println(se.getMessage());
System.exit(1);
} catch (IOException ioe) {
System.err.println(ioe);
System.exit(1);
}
}
// 当每次碰到一个book 元素的时候,将计数器加一。此方法在遇到第一个元素的时候开始执行
public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException {
if (rawName.equals("book"))
count++;
}
// 输出计数器。此方法在分析文档完成的时候执行
public void endDocument() throws SAXException {
System.out.print(count);
}
public static void main(String[] args) throws Exception {
BookCounter bc = new BookCounter();
bc.countBooks();
}
}
我们可以看到输出了结果为3
试着把books.xml 文件改成错误的结构,看看会有什么例外抛出。
于事件驱动的解析接口SAX (实例二)
实例二、查查看我的书架中有多少本小说书(获取元素的属性值)
题目是要查出来下面的XML 文件books.xml 里有多少本小说。
<?xml version="1.0" encoding="gb2312"?>
<书架>
<书类别="参考书">
<著者>谭浩强</著者>
<书名>学习C</书名>
<价格>20.00</价格>
</书>
<书类别="小说">
<著者>吴承恩</著者>
<书名>西游记</书名>
<价格>120.56</价格>
</书>
<书类别="小说">
<著者>曹雪芹</著者>
<书名>红楼梦</书名>
<价格>208.99</价格>
</书>
<书类别="小说">
<著者>睡虫</著者>
<书名>下月出版</书名>
<价格>0.00</价格>
</书>
</书架>
下面的代码使用了SUN 的JAXP 包,请在http://java.sun.com/xml/download.html 下载。
在Jbuilder4 中运行正确。请注意将要分析的xml 文件放在/books.xml 或者更改此URI
import org.xml.sax.*;
import javax.xml.parsers.*;
/**
* Title: XML Study, Sample 2
* Description: Count fictions in my shelf.
* Copyright: Copyright ? 2001
* Company: Isolation Land.
* @author Slepworm
* @version 1.0
*/
public class GetAtts extends org.xml.sax.helpers.DefaultHandler{
private int count = 0; // 定义一个计数器
private boolean isFiction;
public GetAtts() {
}
// 创建一个新的JAXP 的SAXParserFactory 实例,并且配置它。
Public void createParser() throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setValidating(false);
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(this);
xr.parse("/books.xml");
}
// 当每次碰到一个book 元素的时候,将计数器加一。此方法在遇到第一个元素的时候开始执行
public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException {
if (rawName.equals("书")) {
String category = atts.getValue("类别"); ///**** 获取类别的值
System.out.println(category); //打印类别的值
isFiction = (category != null && category.equals("小说")); //如果类别的值为小说则将计数器加一。
If (isFiction) count++;
}
}
// 输出计数器。此方法在分析文档完成的时候执行
public void endDocument() throws SAXException {
System.out.print(count);
}
public static void main(String[] args) throws Exception {
BookCounter ga = new GetAtts();
ga.createParser();
}
}
输出结果为
参考书
小说
小说
小说
3
基于事件驱动的解析接口SAX (实例三)
实例三、计算订单的总价格(如何取出正文的值)。
问题:请计算orders.xml 所示的总价格
orders.xml 的源文件。
<?xml version="1.0" encoding="gb2312"?>
<订单>
<商品数量="21">
<名称>袜子</名称>
<单价>3.24</单价>
</商品>
<商品数量="1">
<名称>贝斯</名称>
<单价>4200.00</单价>
</商品>
<商品数量="5">
<名称>域名</名称>
<单价>60.50</单价>
</商品>
<商品数量="2">
<名称>书</名称>
<单价>99.00</单价>
</商品>
</订单>
下面的代码使用了SUN 的JAXP 包,请在http://java.sun.com/xml/download.html 下载。
在Jbuilder4 中运行正确。
Import org.xml.sax.*;
import javax.xml.parsers.*;
import java.util.Vector;
/**
* Title: XML Study, Sample 3
* Description: Count the Order Sum.
* Copyright: Copyright ? 2001
* Company: Isolation Land.
* @author Slepworm
* @version 1.0
*/
public class CountSum extends org.xml.sax.helpers.DefaultHandler {
private double totalPrice = 0.00;
private StringBuffer content = new StringBuffer();
private Vector numberV = new Vector();
private Vector priceV = new Vector();
private double totalSum = 0.00;
public CountSum() {
}
public static void main(String[] args) throws Exception {
CountSum cs = new CountSum();
cs.createParser();
}
public void createParser() throws Exception{
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setValidating(false);
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(this);
xr.parse("/orders.xml");
}
// 取得商品中属性数量的值,并将它放入数组numberV 中。
Public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException {
if (rawName.equals("商品")) {
String number = atts.getValue("数量");
numberV.addElement(number);
//System.out.println(numberV);
}
content.setLength(0);
}
// **** 此方法将遍历XML 文件,获取文本值。
Public void characters(char[] ch, int start, int length) throws SAXException {
content.append(ch, start, length);
//System.out.println(content.toString()); // 打印出来,看看此方法是怎样运行的
}
// **** 仅获取元素单价中的文本,并将它放入数组priceV 中。
Public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equals("单价")) {
String price = content.toString();
priceV.addElement(price);
//System.out.println(priceV);
}
}
// 计算总价格
public void endDocument() throws SAXException {
int num;
double pr;
for (int I=0; I<numberV.size();I++){
num = Integer.valueOf(numberV.get(I).toString()).intValue();
pr = new Double(priceV.get(I).toString()).doubleValue();
totalSum += pr*num;
}
System.out.println("订单的总价格是" + totalSum);
}
}
输出结果:
订单的总价格是4768.54(完)
站内搜索