以文本方式查看主题

-  W3CHINA.ORG讨论区 - 语义网·描述逻辑·本体·RDF·OWL  (http://bbs.xml.org.cn/index.asp)
--  『 XML源码及示例(仅原创和转载) 』  (http://bbs.xml.org.cn/list.asp?boardid=32)
----  XML编程研究  (http://bbs.xml.org.cn/dispbbs.asp?boardid=32&rootid=&id=9443)


--  作者:卷积内核
--  发布时间:8/19/2004 10:14:00 AM

--  XML编程研究

--------------------------------------------------------------------------------


基于事件驱动的解析接口SAX (实例一)
  SAX 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("http://localhost/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 文件放在http://localhost/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("http://localhost/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("http://localhost/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(完)  

W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
46.875ms