xml | Digester

SAX和DOM的区别是什么?

SAX使用基于event的处理来阅读XML文档, 它由回调机制实现.当解析器阅读文档的时候,每个解析事件都导致与这个事件相关的特定方法的调用,如认出元素的开始和结束.但是,SAX本身不是XML文档解析器.它是对XML解析器接口的公有域定义,在这里解析器是外部程序.SAX API的公有域部分存在于作为JDK一部分的3个程序包内:

1)org.xml.sax 2)org.xml.sax.helpers 3)org.xml.sax.ext   4)javax.xml.parsers  5)javax.xml.transform

在java术语中包含若干个接口.XMLReader接口定义在org.xml.sax包内.

DOM解析XML文档时,整个文档树都在内存中形成,并作为封装好的Document类型的对象返回个应用程序.它的缺点是占用了大量的内存空间.无论它多大都要全部调入内存空间.但是DOM允许你修改存在的文档或创建新的文档.如果需要利用程序创建XML文档并且将它传送给一个文件或另一个计算机这样的外部目标,DOM就可以大显身手了,而SAX则没有这样的功能.

用Digester解析XML文档

Digester是一个将配置文件转换为java对象的工具,有三个核心概念:

1)元素匹配规则Pattern :       找出xml配置文件中匹配的部分准备处理

2)处理规则Rule:                    指定一个处理的规则来处理这些待处理元素

3)对象栈:                                 按照解析的层次关系,将XML配置文件中解析出的对象依次入栈

Digester解析步骤:

1)创建一个Digester的实例:

2)指定其使用的Pattern和Rule;

3)传递一个引用xml文件的对象参数;

以工作流管理系统为例(blog里有关于工作流管理系统模型):

xml配置文件workflow.xml:

<?xml version="1.0" encoding="gb2312"?>
<workflow name ="hello workflow">
 <activities>
  <start name="start" id="0001" nextIds="0002,003">
  </start>
  
  <task name="task"  id="0002" nextIds="0004">
  </task>
  
  <task name="task1"  id="0003" nextIds="0004">
  </task>
  
  <join name="join"  id="0004" nextIds="0005">
  </join>
  
  <end name="end"  id="0005" nextIds="">
  </end>
 </activities>
</workflow>

 指定pattern和rule的xml解析文件rule.xml

<?xml version="1.0"?>
<digester-rules>
 <pattern value="workflow">
  <object-create-rule
   classname="com.itcast.workflow.model.Workflow"/>
  <set-properties-rule />
  <set-next-rule methodname="setWorkflow" />
  
  <pattern value="activities/start">
   <object-create-rule
    classname="com.itcast.workflow.model.Start"/>
   <set-properties-rule />
   <set-next-rule methodname="addActivity" />
  </pattern>
  
  
  <pattern value="activities/task">
   <object-create-rule
    classname="com.itcast.workflow.model.Task"/>
   <set-properties-rule />
   <set-next-rule methodname="addActivity" />
  </pattern>
  
  <pattern value="activities/join">
   <object-create-rule
    classname="com.itcast.workflow.model.Join"/>
   <set-properties-rule />
   <set-next-rule methodname="addActivity" />
  </pattern>
  
  
  <pattern value="activities/end">
   <object-create-rule
    classname="com.itcast.workflow.model.End"/>
   <set-properties-rule />
   <set-next-rule methodname="addActivity" />
  </pattern>
  
 </pattern>
</digester-rules>

XMLReader.java:

import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.xml.sax.SAXException;

import com.itcast.workflow.model.Activity;
import com.itcast.workflow.model.Workflow;

public class XmlReader {

     public void setWorkflow(Workflow workflow) {
     this.workflow = workflow;
 }

public XmlReader(String xml) {
     this.xml = xml;
 }
 
 
 public void startRead(){
  try
        {

            java.net.URL rulesURL = getClass().getClassLoader().getResource("com/itcast/workflow/xml/rules.xml");
//          创建digester对象并指定解析规则
            Digester d = DigesterLoader.createDigester(rulesURL);
           
//回调机制

            d.push(this);         //压入栈中
            d.parse(new StringReader(xml));  //弹出栈
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
        catch(SAXException se)
        {
            se.printStackTrace();
        }
        buildRelation();
 }
 
 
 private void buildRelation() {//建立关联
  List activities = workflow.getActivities();
  for(int i=0;i<activities.size();i++){
   Activity activity = (Activity )activities.get(i);
   
   String nextIds = activity.getNextIds();
   if(nextIds != null){
    String[] ids = nextIds.split(",");
    for(int j=0;j<ids.length;j++){
     Activity next = getActivityById(ids[j]);
     if(next != null){
      activity.addNext(next);
     }
    }
   }
   
   
  }
  
 }


 private Activity getActivityById(String id) {
  
  Activity activity = null;
  
  List activities = workflow.getActivities();
  for(int i=0;i<activities.size();i++){
   Activity a = (Activity )activities.get(i);
   if(a.getId().equals(id)){
    activity = a;
    break;
   }
  }
  return activity;
 }

String xml;
 
 Workflow workflow = new Workflow();

public Workflow getWorkflow() {
  return workflow;
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值