java sax解析xml文档

    java的sax解析是基于事件的解析:当解析到xml的某个部分的时候,会触发特定事件,可以在自定义的解析类中定义当事件触发时要做得事情。

    我们可以继承org.xml.sax.helpers.DefaultHandler类(该类是org.xml.sax.helpers.ContentHandler的接口实现类)来覆盖ContentHandler接口的各种方法,这些方法将定义各个事件所触发的程序动作。

package com.thomas.xml.sax;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ThomasSAXHandler extends DefaultHandler {
 
 private StringBuffer xml;//格式化后的XML文件内容
 private static int step = 0;//元素层次
 
 public ThomasSAXHandler(){
  this.xml = new StringBuffer();
 }
 
 public StringBuffer getXml() {
  return xml;
 }
 public void setXml(StringBuffer xml) {
  this.xml = xml;
 }
 /**
   * 给字符串添加TAB,使其能格式化输出,在这里第step层元素缩进step个Tab
   */
 private void appendTab(){
  for(int i = 1 ; i<step; i++){
   for(int j = 0 ;j<4; j++){
    xml.append(' ');
   }
  }
 }
 /**
   * 接收元素中字符数据的通知。
   * @param ch - 字符。
   * @param start - 字符数组中的开始位置。
   * @param length - 从字符数组中使用的字符数。
   */
 public void characters(char[] ch, int start, int length) throws SAXException {
  String text = new String(ch,start,length);
  text = text.trim();
  if(!text.equals("")){
      step++;
      appendTab();
      xml.append(text).append("/r/n");
      step--;
     }
 }
 /**
  * 接收文档的结尾的通知。
  * @exception SAXException - 任何 SAX 异常,可能包装另外的异常。
  */
 public void endDocument() throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
    * 接收元素结束的通知  
    * @param uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
    * @param localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
    * @param qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
    * @exception SAXException - 任何 SAX 异常,可能包装另外的异常。
    */
 public void endElement(String uri, String localName, String qName) throws SAXException {
  appendTab();
  xml.append("</");
  if(!uri.equals("")){
   xml.append(uri+":");
  }
  xml.append(qName).append(">/r/n");
  step--;

 }
 /**
  * 结束前缀 URI 范围的映射。
  * @param prefix - 被映射的前缀。当默认的映射范围结束时,这是一个空字符串。
  * @exception SAXException - 客户端可能会在处理期间抛出一个异常
  */
 public void endPrefixMapping(String prefix) throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
  * 接收元素内容中可忽略的空白的通知。
  * @param ch 来自 XML 文档的字符
  * @param start 数组中的开始位置
  * @param length 从数组中读取的字符的个数
  * @exception SAXException - 任何 SAX 异常,可能包装另外的异常
  */
 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
  * 接收处理指令的通知。
  * @param target 处理指令目标
  * @param data 处理指令数据,如果未提供,则为 null。该数据不包括将其与目标分开的任何空白
  */
 public void processingInstruction(String target, String data) throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
  * 接收用来查找 SAX 文档事件起源的对象
  * @param locator 可以返回任何 SAX 文档事件位置的对象
  */
 public void setDocumentLocator(Locator locator) {
  // TODO Auto-generated method stub

 }
 /**
  * 接收跳过的实体的通知。将不为标记结构(如元素开始标记或标记声明)内的实体引用调用此方法。(XML 建议书要求报告所跳过的外部实体。SAX 还报告内部实体扩展 / 非扩展,但不包括在标记结构内部。)
  * @param name - 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头,如果它是外部 DTD 子集,则将是字符串 "[dtd]"
  * @exception SAXException - 任何 SAX 异常,可能包装另外的异常
  */
 public void skippedEntity(String name) throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
  * 接收文档的开始的通知
  * @exception - SAXException - 任何 SAX 异常,可能包装另外的异常
  */
 public void startDocument() throws SAXException {
  // TODO Auto-generated method stub

 }
 /**
   * 接收元素开始的通知。
   * @param uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
   * @param localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
   * @param qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
   * @param attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。
   * @exception SAXException - 任何 SAX 异常,可能包装另外的异常
   */
 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  step++;//元素层次加一
  appendTab();
  xml.append("<");
  if(!uri.equals("")){
   xml.append(uri+":");
  }
  xml.append(qName);
  for(int i = 0, size = attributes.getLength(); i<size; i++){
      xml.append(' ').append(attributes.getQName(i)).append("=/"").append(attributes.getValue(i)).append("/"");
  }
  xml.append(">/r/n");
 }
 /**
  * 开始前缀 URI 名称空间范围映射。
  * @param prefix - 声明的名称空间前缀。对于没有前缀的默认元素名称空间,使用空字符串。
  * @param uri - 将前缀映射到的名称空间 URI
  * @exception - SAXException - 客户端可能会在处理期间抛出一个异常
  */
 public void startPrefixMapping(String prefix, String uri) throws SAXException {
  // TODO Auto-generated method stub

 }

}

 

    上面是我们自定义的解析器,可以在带有main方法的类中加以测试

package com.thomas.xml.sax;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;


public class Test {
 public static void main(String[] args){
    try{  
        SAXParserFactory sf  = SAXParserFactory.newInstance();
        SAXParser sp = sf.newSAXParser();
        ThomasSAXHandler handler = new ThomasSAXHandler();
        sp.parse(new InputSource("film.xml"),handler);
        System.out.println(handler.getXml());
    }
    catch(Exception e){
     e.printStackTrace();
    }
   }
}
下面是Kungfu.xml

<?xml version="1.0" encoding="gb2312"?>
<Kungfu-vips>
<vip>
   <name lang="en,ch">Bruce Li</name>
   <age>32</age>
   <sex>male</sex>
</vip>
<vip>
   <name lang="en,ch">Jakie Chen</name>
   <age>39</age>
   <sex>male</sex>
</vip>
<vip>
   <name lang="en,ch">Jet Li</name>
   <age>39</age>
   <sex>male</sex>
</vip>
</Kungfu-vips>

运行test类,可以看到输出结果:

<Kungfu-vips>
    <vip>
        <name lang="en,ch">
            Bruce Li
        </name>
        <age>
            32
        </age>
        <sex>
            male
        </sex>
    </vip>
    <vip>
        <name lang="en,ch">
            Jakie Chen
        </name>
        <age>
            39
        </age>
        <sex>
            male
        </sex>
    </vip>
    <vip>
        <name lang="en,ch">
            Jet Li
        </name>
        <age>
            39
        </age>
        <sex>
            male
        </sex>
    </vip>
</Kungfu-vips>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值