俊星的BLOG

JAVA SAX之我的Digester

Apache Common Digester是一个很优秀的XML解析工具,居于SAX技术,下面是我一个简单实现(点击下载源代码):
1、类图:

2、规则定义:
2-1、MyRule抽象类:
package mydigest;

import org.xml.sax.Attributes;

/**
 * 规则抽象类
 * 
@author kinkding
 
*/

public abstract class MyRule {
    
protected MyDigester dig = null;
    
protected String namespaceURI = null;

    
public void setDigester(MyDigester dig) {
        
this.dig = dig;
    }


    
public void setNamespaceURI(String namespaceURI) {
        
this.namespaceURI = namespaceURI;
    }


    
public String getNamespaceURI() {
        
return this.namespaceURI;
    }


    
/** 规则使用完成 */
    
public void finish() throws Exception {

    }


    
/** 开始处理 */
    
public void begin(String namespace, String name, Attributes attributes) throws Exception {

    }


    
/** 处理中 */
    
public void body(String namespace, String name, String text) throws Exception {

    }


    
/** 处理结束 */
    
public void end(String namespace, String name) throws Exception {

    }


}


2-2、创建对象规则:
package mydigest;

import org.xml.sax.Attributes;

/** 创建对象 */
public class MyObjCreateRule extends MyRule {
    
protected String className = null;

    
public MyObjCreateRule(Class<?> clazz) {
        
this.className = clazz.getName();
    }


    
public void begin(String namespace, String name, Attributes attributes) throws Exception {
        String realClassName 
= className;
        
if (name != null{
            
// 形如:person="com.info.Person"
            String value = attributes.getValue(name);
            
if (value != null{
                realClassName 
= value;
            }

        }

        
        
// 创建实例并放置到堆栈中
        Class<?> clazz = dig.getClassLoader().loadClass(realClassName);
        Object instance 
= clazz.newInstance();
        dig.push(instance);
    }


    
public void end(String namespace, String name) throws Exception {
        
// 从堆栈中弹出对象
        dig.pop();
    }

}


2-3、设置属性规则:
package mydigest;

import java.util.HashMap;

import org.apache.commons.beanutils.BeanUtils;
import org.xml.sax.Attributes;

public class MySetPropRule extends MyRule {
    
public void begin(String namespace, String name, Attributes attributes) throws Exception {
        HashMap
<String, String> values = new HashMap<String, String>();
        
// 获取属性及值
        for (int i = 0; i < attributes.getLength(); i++{
            String temp 
= attributes.getLocalName(i);
            
if ("".equals(temp)) {
                temp 
= attributes.getQName(i);
            }

            String value 
= attributes.getValue(i);
            
if (temp != null{
                values.put(temp, value);
            }

        }


        Object top 
= dig.peek();
        BeanUtils.populate(top, values);
    }

}


2-4、MySetNextRule:
package mydigest;

import org.apache.commons.beanutils.MethodUtils;

public class MySetNextRule extends MyRule {
    
protected String methodName = null;

    
public MySetNextRule(String methodName) {
        
this.methodName = methodName;
    }


    
public void end(String namespace, String name) throws Exception {
        Object child 
= dig.peek(0);
        Object parent 
= dig.peek(1);

        Class
<?> paramTypes[] = new Class<?>[1];
        paramTypes[
0= child.getClass();
        MethodUtils.invokeMethod(parent, methodName, 
new Object[] { child }, paramTypes);
    }

}


2-5、方法调用规则:
package mydigest;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.xml.sax.Attributes;

public class MyCallMethodRule extends MyRule {
    
protected int targetOffset = 0;
    
protected String methodName = null;
    
protected int paramCount = 0;
    
protected Class<?> paramTypes[] = null;
    
protected String bodyText = null;

    
public MyCallMethodRule(int targetOffset, String methodName, int paramCount) {
        
this.targetOffset = targetOffset;
        
this.methodName = methodName;
        
this.paramCount = paramCount;
        
// 参数类型初始化
        if (paramCount == 0{
            
this.paramTypes = new Class[] { String.class };
        }
 else {
            
this.paramTypes = new Class[paramCount];
            
for (int i = 0; i < this.paramTypes.length; i++{
                
this.paramTypes[i] = String.class;
            }

        }

    }


    
public void begin(String namespace, String name, Attributes attributes) throws Exception {
        
if (paramCount > 0{
            Object parameters[] 
= new Object[paramCount];
            
for (int i = 0; i < parameters.length; i++{
                parameters[i] 
= null;
            }

            
// 参数入栈
            dig.pushParams(parameters);
        }


    }


    
public void body(String namespace, String name, String text) throws Exception {
        
// 只针对0个参数的情况提取元素中间值
        if (paramCount == 0{
            
this.bodyText = text.trim();
        }

    }


    
public void end(String namespace, String name) throws Exception {
        Object parameters[] 
= null;
        
if (paramCount > 0{
            parameters 
= (Object[]) dig.popParams();
            
if (paramCount == 1 && parameters[0== null{
                
return;
            }

        }
 else if (paramTypes != null && paramTypes.length != 0{
            
if (bodyText == null{
                
return;
            }

            parameters 
= new Object[1];
            parameters[
0= bodyText;
            
if (paramTypes.length == 0{
                paramTypes 
= new Class[1];
                paramTypes[
0= String.class;
            }

        }


        Object paramValues[] 
= new Object[paramTypes.length];
        
for (int i = 0; i < paramTypes.length; i++{
            
// 确定是否需要转换
            if (parameters[i] == null
                    
|| (parameters[i] instanceof String && !String.class.isAssignableFrom(paramTypes[i]))) {

                paramValues[i] 
= ConvertUtils.convert((String) parameters[i], paramTypes[i]);
            }
 else {
                paramValues[i] 
= parameters[i];
            }

        }


        Object target;
        
if (targetOffset >= 0{
            target 
= dig.peek(targetOffset);
        }
 else {
            target 
= dig.peek(dig.getCount() + targetOffset);
        }

        
if (target == null{
            StringBuffer sb 
= new StringBuffer();
            sb.append(
"[CallMethodRule]{");
            sb.append(dig.match);
            sb.append(
"} Call target is null (");
            sb.append(
"targetOffset=");
            sb.append(targetOffset);
            sb.append(
",stackdepth=");
            sb.append(dig.getCount());
            sb.append(
")");
            
throw new org.xml.sax.SAXException(sb.toString());
        }

        MethodUtils.invokeMethod(target, methodName, paramValues, paramTypes);
    }

}


2-6、参数调用规则:
package mydigest;

import java.util.Stack;

import org.xml.sax.Attributes;

public class MyCallParamRule extends MyRule {
    
protected String attributeName = null;
    
protected int paramIndex = 0;
    
protected Stack<String> bodyTextStack;

    
public MyCallParamRule(int paramIndex, String attributeName) {
        
this.paramIndex = paramIndex;
        
this.attributeName = attributeName;
    }


    
public void begin(String namespace, String name, Attributes attributes) throws Exception {
        Object param 
= null;
        
if (attributeName != null{
            param 
= attributes.getValue(attributeName);
        }


        
if (param != null{
            
// 给参数赋值
            Object parameters[] = (Object[]) dig.peekParams();
            parameters[paramIndex] 
= param;
        }

    }


    
public void body(String namespace, String name, String text) throws Exception {
         
if (attributeName == null{
                
if (bodyTextStack == null{
                    bodyTextStack 
= new Stack<String>();
                }

                bodyTextStack.push(text.trim());
            }

    }


    
public void end(String namespace, String name) throws Exception {
        
if (bodyTextStack != null && !bodyTextStack.empty()) {
            Object parameters[] 
= (Object[]) dig.peekParams();
            parameters[paramIndex] 
= bodyTextStack.pop();
        }

    }


}


2-7、嵌套属性设置:
package mydigest;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.xml.sax.Attributes;

public class MySetNestedPropRule extends MyRule {

    
public void begin(String namespace, String name, Attributes attributes) throws Exception {
        AnyChildRule anyChildRule 
= new AnyChildRule();
        anyChildRule.setDigester(dig);
        AnyChildRules newRules 
= new AnyChildRules(anyChildRule);
        newRules.init(dig.getMatch() 
+ "/", dig.getRules());
        dig.setRules(newRules);
    }


    
private class AnyChildRules implements MyRules {
        
private MyRules decoratedRules = null;
        
private String matchPrefix = null;
        
private ArrayList<MyRule> rules = new ArrayList<MyRule>(1);
        
private AnyChildRule rule;

        
public AnyChildRules(AnyChildRule rule) {
            
this.rule = rule;
            rules.add(rule);
        }


        
public void add(String pattern, MyRule rule) {

        }


        
public List<MyRule> match(String namespaceURI, String pattern) {
            List
<MyRule> match = decoratedRules.match(namespaceURI, pattern);
            
if ((pattern.startsWith(matchPrefix)) && (pattern.indexOf('/', matchPrefix.length()) == -1)) {
                
if ((match == null || match.size() == 0)) {
                    
return rules;
                }
 else {
                    LinkedList
<MyRule> newMatch = new LinkedList<MyRule>(match);
                    newMatch.addLast(rule);
                    
return newMatch;
                }

            }
 else {
                
return match;
            }

        }


        
public List<MyRule> rules() {
            
return decoratedRules.rules();
        }


        
public void setDigester(MyDigester dig) {
        }


        
public void init(String prefix, MyRules rules) {
            matchPrefix 
= prefix;
            decoratedRules 
= rules;
        }


        
public MyRules getOldRules() {
            
return decoratedRules;
        }


    }


    
private class AnyChildRule extends MyRule {
        
private String currChildElementName = null;

        
public void begin(String namespace, String name, Attributes attributes) throws Exception {
            currChildElementName 
= name;
        }


        
public void body(String namespace, String name, String text) throws Exception {
            String propName 
= currChildElementName;
            Object top 
= dig.peek();
            text 
= text.trim();

            
// 验证是否存在相应属性
            PropertyDescriptor desc = PropertyUtils.getPropertyDescriptor(top, propName);
            
if (desc == null{
                
throw new NoSuchMethodException("Bean has no property named " + propName);
            }

            
try {
                BeanUtils.setProperty(top, propName, text);
            }
 catch (NullPointerException e) {
                
throw e;
            }

        }


        
public void end(String namespace, String name) throws Exception {
            currChildElementName 
= null;
        }

    }

}


3、MyRules及其实现类:
3-1、接口:

package mydigest;

import java.util.List;

public interface MyRules {
    
public void setDigester(MyDigester dig);

    
public void add(String pattern, MyRule rule);

    
public List<MyRule> rules();

    
public List<MyRule> match(String namespaceURI, String pattern);
}

3-2、实现类:
package mydigest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MyRulesBase implements MyRules {
    
protected MyDigester digester = null;
    
// 缓存:同一个pattern会对应多个规则
    protected HashMap<String, List<MyRule>> cache = new HashMap<String, List<MyRule>>();
    
protected String namespaceURI = null;
    
// 所有规则列表
    protected ArrayList<MyRule> rules = new ArrayList<MyRule>();

    
public void setDigester(MyDigester dig) {
        
this.digester = dig;
    }


    
public void add(String pattern, MyRule rule) {
        
int patternLength = pattern.length();
        
// 去掉最后一个斜线
        if (patternLength > 1 && pattern.endsWith("/")) {
            pattern 
= pattern.substring(0, patternLength - 1);
        }


        List
<MyRule> list = cache.get(pattern);
        
if (list == null{
            list 
= new ArrayList<MyRule>();
            cache.put(pattern, list);
        }

        list.add(rule);
        rules.add(rule);
        
if (this.digester != null{
            rule.setDigester(
this.digester);
        }

        
if (this.namespaceURI != null{
            rule.setNamespaceURI(
this.namespaceURI);
        }

    }


    
public List<MyRule> rules() {
        
return this.rules;
    }


    
public List<MyRule> match(String namespaceURI, String pattern) {
        List
<MyRule> rulesList = lookup(namespaceURI, pattern);
        
if ((rulesList == null|| (rulesList.size() < 1)) {
            String longKey 
= "";
            
for (String key : cache.keySet()) {
                
if (key.startsWith("*/")) {
                    
// pattern -> key:
                    
// (1):foo -> */foo 
                    
// (2):foo/bar->*/bar
                    if (pattern.equals(key.substring(2)) || pattern.endsWith(key.substring(1))) {
                        
// 查找最匹配的
                        if (key.length() > longKey.length()) {
                            rulesList 
= lookup(namespaceURI, key);
                            longKey 
= key;
                        }

                    }

                }

            }

        }

        
if (rulesList == null{
            rulesList 
= new ArrayList<MyRule>();
        }

        
return (rulesList);
    }


    
/** 根据patter查找匹配的规则列表 */
    
protected List<MyRule> lookup(String namespaceURI, String pattern) {
        List
<MyRule> list = this.cache.get(pattern);
        
if (list == null{
            
return (null);
        }

        
if ((namespaceURI == null|| (namespaceURI.length() == 0)) {
            
return (list);
        }


        ArrayList
<MyRule> results = new ArrayList<MyRule>();
        
for (MyRule item : list) {
            
if ((namespaceURI.equals(item.getNamespaceURI())) || (item.getNamespaceURI() == null)) {
                results.add(item);
            }

        }

        
return (results);

    }


}


4、Digester类:
package mydigest;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class MyDigester extends DefaultHandler {
    
// 堆栈
    protected Stack<Object> stack = new Stack<Object>();
    
// 根对象
    protected Object root = null;
    
// 
    protected MyRules rules = null;
    
protected XMLReader reader = null;
    
protected SAXParser parser = null;
    
protected Stack<StringBuffer> bodyTexts = new Stack<StringBuffer>();
    
protected StringBuffer bodyText = new StringBuffer();
    
protected String match = "";
    
protected Stack<List<MyRule>> matches = new Stack<List<MyRule>>();
    
protected ClassLoader classLoader = null;
    
protected Stack<Object> params = new Stack<Object>();

    
public void push(Object object) {
        
if (stack.size() == 0{
            root 
= object;
        }

        stack.push(object);
    }


    
public void addRule(String pattern, MyRule rule) {
        rule.setDigester(
this);
        getRules().add(pattern, rule);
    }


    
public MyRules getRules() {
        
if (this.rules == null{
            
this.rules = new MyRulesBase();
            
this.rules.setDigester(this);
        }

        
return this.rules;

    }


    
public void addObjectCreate(String pattern, Class<?> clazz) {
        addRule(pattern, 
new MyObjCreateRule(clazz));
    }


    
public void addSetProperties(String pattern) {
        addRule(pattern, 
new MySetPropRule());
    }


    
public void addSetNext(String pattern, String methodName) {
        addRule(pattern, 
new MySetNextRule(methodName));
    }


    
public void addCallMethod(String pattern, String methodName, int paramCount) {
        addRule(pattern, 
new MyCallMethodRule(0, methodName, paramCount));
    }


    
public void addCallParam(String pattern, int paramIndex, String attributeName) {
        addRule(pattern, 
new MyCallParamRule(paramIndex, attributeName));
    }


    
public void addCallParam(String pattern, int paramIndex) {
        addRule(pattern, 
new MyCallParamRule(paramIndex, null));
    }


    
public void addSetNestedProperties(String pattern) {
        addRule(pattern, 
new MySetNestedPropRule());
    }


    
public Object parse(File file) throws Exception {
        InputSource input 
= new InputSource(new FileInputStream(file));
        input.setSystemId(file.toURI().toURL().toString());
        getXMLReader().parse(input);
        
return root;
    }


    
public XMLReader getXMLReader() throws Exception {
        
if (reader == null{
            reader 
= getParser().getXMLReader();
        }

        reader.setDTDHandler(
this);
        reader.setContentHandler(
this);
        reader.setEntityResolver(
this);
        reader.setErrorHandler(
this);
        
return reader;
    }


    
public SAXParser getParser() throws Exception {
        
if (parser != null{
            
return (parser);
        }

        parser 
= SAXParserFactory.newInstance().newSAXParser();
        
return parser;
    }


    
public void startDocument() throws SAXException {
    }


    
public void endDocument() throws SAXException {
        
for (MyRule r : this.getRules().rules()) {
            
try {
                r.finish();
            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

        stack.clear();
    }


    
public void startElement(String namespaceURI, String localName, String fullName, Attributes attributes)
            
throws SAXException {
        bodyTexts.push(bodyText);
        bodyText 
= new StringBuffer();
        String name 
= localName;
        
if ((name == null|| (name.length() < 1)) {
            name 
= fullName;
        }

        StringBuffer sb 
= new StringBuffer(match);
        
if (match.length() > 0{
            sb.append(
'/');
        }

        sb.append(name);
        
// 得到新的匹配字符
        match = sb.toString();
        List
<MyRule> rules = getRules().match(namespaceURI, match);
        matches.push(rules);
        
if ((rules != null&& (rules.size() > 0)) {
            
for (int i = 0; i < rules.size(); i++{
                
try {
                    MyRule rule 
= rules.get(i);
                    rule.begin(namespaceURI, name, attributes);
                }
 catch (Exception e) {
                    e.printStackTrace();
                    
throw new SAXException(e);
                }

            }

        }

    }


    
public void characters(char buffer[], int start, int length) throws SAXException {
        bodyText.append(buffer, start, length);
    }


    
public void endElement(String namespaceURI, String localName, String fullName) throws SAXException {
        String name 
= localName;
        
if ((name == null|| (name.length() < 1)) {
            name 
= fullName;
        }

        List
<MyRule> rules = matches.pop();
        
if ((rules != null&& (rules.size() > 0)) {
            String bodyText 
= this.bodyText.toString();
            
for (int i = 0; i < rules.size(); i++{
                
try {
                    MyRule rule 
= rules.get(i);
                    rule.body(namespaceURI, name, bodyText);
                }
 catch (Exception e) {
                    e.printStackTrace();
                    
throw new SAXException(e);
                }

            }

        }

        
// bodyText 退栈
        bodyText = bodyTexts.pop();
        
if (rules != null{
            
// 顺序是从后到前
            for(int i=rules.size()-1;i>=0;i--){
                
try {
                    MyRule rule 
= rules.get(i);
                    rule.end(namespaceURI, name);
                }
 catch (Exception e) {
                    e.printStackTrace();
                    
throw new SAXException(e);
                }

            }

        }


        
// 将匹配字符向前回缩一个单元
        int slash = match.lastIndexOf('/');
        
if (slash >= 0{
            match 
= match.substring(0, slash);
        }
 else {
            match 
= "";
        }

    }


    
public ClassLoader getClassLoader() {
        
if (this.classLoader != null{
            
return (this.classLoader);
        }

        ClassLoader classLoader 
= Thread.currentThread().getContextClassLoader();
        
if (classLoader != null{
            
return (classLoader);
        }

        
return (this.getClass().getClassLoader());
    }


    
public Object peek() {
        
// 取得最后入栈的对象
        return this.stack.peek();
    }


    
// 0:最后一个入栈的对象
    public Object peek(int n) {
        
int index = (stack.size() - 1- n;
        
if (index < 0{
            
return (null);
        }

        
// 第一个入栈的index为0,之后递增
        return (stack.get(index));
    }


    
public Object pop() {
        
return this.stack.pop();
    }


    
public int getCount() {
        
return (stack.size());
    }


    
public void pushParams(Object object) {
        
this.params.push(object);
    }


    
public Object popParams() {
        
return this.params.pop();
    }


    
public Object peekParams() {
        
return this.params.peek();
    }


    
public String getMatch() {
        
return match;
    }


    
public void setRules(MyRules rules) {
        
this.rules = rules;
        
this.rules.setDigester(this);
    }


}

5、测试:
5-1、业务类:
public class AddressBook {
    LinkedList people 
= new LinkedList();
    
    
public void addPerson(Person p) {
        people.addLast(p);
    }
    
    
public void print() {
        System.out.println(
"Address book has " + people.size() + " entries");
        
for(Iterator i = people.iterator(); i.hasNext(); ) {
            Person p 
= (Person) i.next();
            p.print();
        }
    }
}

public class Person {
  
private int id;
  
private String category;
  
private String name;
  
private HashMap emails = new HashMap();
  
private List addresses = new ArrayList();
  
  
/** 
   * A unique id for this person. Note that the Digester automatically
   * converts the id to an integer.
   
*/
  
public void setId(int id) {
      
this.id = id;
  }
  
  
public void setCategory(String category) {
      
this.category = category;
  }
  
  
public void setName(String name) {
      
this.name = name;
  }
  
  
/** we assume only one email of each type */
  
public void addEmail(String type, String address) {
      emails.put(type, address);
  }
  
  
public void addAddress( Address addr ) {
     addresses.add( addr );
  }

  
public void print() {
      System.out.println(
"Person #" + id);
      System.out.println(
"  category=" + category);
      System.out.println(
"  name=" + name);
      
      
for(Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
          String type 
= (String) i.next();
          String address 
= (String) emails.get(type);
          
          System.out.println(
"  email (type " + type + ") : " + address);
      }
      
      
for(Iterator i = addresses.iterator(); i.hasNext(); ) {
          Address addr 
= (Address) i.next();
          addr.print(System.out, 
2);
      }
  }
}

public class Address {
    
private String type;
    
private String street;
    
private String city;
    
private String state;
    
private String zip;
    
private String country;

    
public String toString() {
        StringBuffer sb 
= new StringBuffer();
        sb.append(
" address (type " + type + ")\n");
        sb.append(
"       " + street + "\n");
        sb.append(
"       " + city + " " + state + " " + zip + "\n");
        sb.append(
"       " + country + "\n");
        
return sb.toString();
    }

    
public void print(java.io.PrintStream out, int indentAmount) {
        StringBuffer indentStr 
= new StringBuffer(indentAmount);
        
for (; indentAmount > 0--indentAmount) {
            indentStr.append(
' ');
        }

        out.print(indentStr);
        out.print(
"address type: ");
        out.println(type);

        out.print(indentStr);
        out.println(
"  " + street);

        out.print(indentStr);
        out.println(
"  " + city + " " + state + " " + zip);

        out.print(indentStr);
        out.println(
"  " + country);
    }

    
public String getStreet() {
        
return street;
    }

    
public void setStreet(String street) {
        
this.street = street;
    }

    
public String getCity() {
        
return city;
    }

    
public void setCity(String city) {
        
this.city = city;
    }

    
public String getState() {
        
return state;
    }

    
public void setState(String state) {
        
this.state = state;
    }

    
public String getZip() {
        
return zip;
    }

    
public void setZip(String zip) {
        
this.zip = zip;
    }

    
public String getCountry() {
        
return country;
    }

    
public void setCountry(String country) {
        
this.country = country;
    }

    
public String getType() {
        
return type;
    }

    
public void setType(String type) {
        
this.type = type;
    }
}

5-2、XML文件:
<?xml version='1.0'?>
<address-book>
  
<person id="1" category="acquaintance">
    
<name>Gonzo</name>
    
<email type="business">gonzo@muppets.com</email>
    
<address>
      
<type>home</type>
      
<street>123 Maine Ave.</street>
      
<city>Las Vegas</city>
      
<state>NV</state>
      
<zip>01234</zip>
      
<country>USA</country>
    
</address>
    
<address>
      
<type>business</type>
      
<street>234 Maple Dr.</street>
      
<city>Los Angeles</city>
      
<state>CA</state>
      
<zip>98765</zip>
      
<country>USA</country>
    
</address>
  
</person>

  
<person id="2" category="rolemodel">
    
<name>Kermit</name>
    
<email type="business">kermit@muppets.com</email>
    
<email type="home">kermie@acme.com</email>
    
<address>
      
<type>business</type>
      
<street>987 Brown Rd</street>
      
<city>Las Cruces</city>
      
<state>NM</state>
      
<zip>75321</zip>
      
<country>USA</country>
    
</address>
  
</person>

</address-book>

5-3、测试类:
public class MyDigestTest {
    
public static void main(String[] args) {
        String file 
= "example.xml";
        MyDigester dig 
= new MyDigester();
        AddressBook book 
= new AddressBook();
        dig.push(book);

        
// 添加生成规则(有先后顺序):
        
// 创建对象
        dig.addObjectCreate("address-book/person", Person.class);
        
// 设置属性
        dig.addSetProperties("address-book/person");
        dig.addSetNext(
"address-book/person""addPerson");
        
// 一个参数的情况
        dig.addCallMethod("address-book/person/name""setName"0);
        
// 两个参数的情况
        dig.addCallMethod("address-book/person/email""addEmail"2);
        dig.addCallParam(
"address-book/person/email"0"type");
        dig.addCallParam(
"address-book/person/email"1);
        dig.addObjectCreate(
"address-book/person/address", Address.class);
        dig.addSetNext(
"address-book/person/address""addAddress");
        dig.addSetNestedProperties(
"address-book/person/address");

        java.io.File srcfile 
= new java.io.File(file);
        
try {
            dig.parse(srcfile);
        } 
catch (Exception e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
        book.print();
    }
}

5-4、输出结果:
Address book has 2 entries
Person #
1
  category
=acquaintance
  name
=Gonzo
  email (type business) : gonzo@muppets.com
  address type: home
    
123 Maine Ave.
    Las Vegas NV 
01234
    USA
  address type: business
    
234 Maple Dr.
    Los Angeles CA 
98765
    USA
Person #
2
  category
=rolemodel
  name
=Kermit
  email (type business) : kermit@muppets.com
  email (type home) : kermie@acme.com
  address type: business
    
987 Brown Rd
    Las Cruces NM 
75321
    USA

posted on 2009-05-01 01:27 俊星 阅读(671) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: