1. 程式人生 > >利用Digester實現xml和bean之間的轉換(二)

利用Digester實現xml和bean之間的轉換(二)

Digester框架屬於Jakarta Commons,它以規則和模式為基礎處理XML文件。與SAX和DOM之類的標準API相比,Digester不涉及太多的細節問題,非常適合於對XML文件進行簡單的處理。
比如要解析如下的xml檔案 
<persons>  
    <person name="tom">
        <age>4</age>  
        <address>  
            <street>no1street</street>  
            <belongarea
>
us</belongarea> </address> <creditcard> <limit code="123" pwd="abc">1000</limit> <bank>ICBC</bank> </creditcard> <creditcard> <limit code="321" pwd="cba">2000</limit
>
<bank>CBC</bank> </creditcard> </person> <person name="jerry"> <age>5</age> <address> <street>no2street</street> <belongarea>us</belongarea> </address
>
</person> </persons>

首先定義address對應的類

public class Address {
    private String street;
    private String belongArea;

    public String getStreet() {
        return street;
    }

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

    public String getBelongArea() {
        return belongArea;
    }

    public void setBelongArea(String belongArea) {
        this.belongArea = belongArea;
    }

    @Override
    public String toString(){
        return "street:" +this.getStreet() + ", belongarea:" + this.getBelongArea();
    }
}

接著定義creditcard對應的類

public class Creditcard {
    private int code;
    private String pwd;
    private String limit;
    private String bank;

    public void setParam(String limit, String bank){
        this.limit = limit;
        this.bank = bank;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getLimit() {
        return limit;
    }

    public void setLimit(String limit) {
        this.limit = limit;
    }

    public String getBank() {
        return bank;
    }

    public void setBank(String bank) {
        this.bank = bank;
    }

    @Override
    public String toString(){
        return "limit code:" + this.getCode() + ", pwd:" + this.getPwd() + ", limitValue:" + this.getLimit() + ", bank:" + this.getBank();
    }
}

接下來定義person對應的類

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

/**
 * Created by Administrator on 2016/7/1 0001.
 */

public class Person {
    private String name;
    private int age;
    private Address address;
    private List<Creditcard> creditcard = new ArrayList<Creditcard>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public List<Creditcard> getCreditcard() {
        return creditcard;
    }

    public void setCreditcard(List<Creditcard> creditcard) {
        this.creditcard = creditcard;
    }

    public void addCreditcard(Creditcard creditcard){
        this.creditcard.add(creditcard);
    }

    @Override
    public String toString(){
        return "name:" + this.getName() + ", age:" + this.getAge() + "\naddress:" + this.getAddress() + "\ncreditcare:" + this.getCreditcard();
     }

}

最後定義persons對應的類

public class Root {
    private List<Person> person = new ArrayList<Person>();

    public List<Person> getPerson() {
        return person;
    }

    public void setPerson(List<Person> person) {
        this.person = person;
    }

    public void addPerson(Person person){
        this.person.add(person);
    }

    @Override
    public String toString(){
        for(Person person : this.getPerson()){
            System.out.print( "person: " + person + "\n");
        }
        return "";
    }
}

需要注意的是,所有的物件都必須是public型別重點內容

然後來寫解析檔案

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

import java.io.File;
import java.io.IOException;


public class Main {

    public static void main(String[] args) {
        //digester
        Digester digester = new  Digester();
        digester.setValidating(false);

        digester.addObjectCreate("persons",Root.class);
        digester.addObjectCreate("persons/person", Person.class);

        //name
        digester.addSetProperties("persons/person", "name", "name");
        //age
        digester.addBeanPropertySetter("persons/person/age");

        //address
        digester.addObjectCreate("persons/person/address",Address.class);
        digester.addBeanPropertySetter("persons/person/address/street");
        digester.addBeanPropertySetter("persons/person/address/belongarea","belongArea");
        digester.addSetNext("persons/person/address","setAddress");

        //creditcard
        digester.addObjectCreate("persons/person/creditcard",Creditcard.class);

        digester.addCallMethod("persons/person/creditcard","setParam",2);
        digester.addCallParam("persons/person/creditcard/limit",0);
        digester.addCallParam("persons/person/creditcard/bank",1);

        /*實現跟上面3條語句同樣的功能
        digester.addBeanPropertySetter("persons/person/creditcard/limit","limit");
        digester.addBeanPropertySetter("persons/person/creditcard/bank","bank");*/
        digester.addSetProperties("persons/person/creditcard/limit","code","code");
        digester.addSetProperties("persons/person/creditcard/limit","pwd","pwd");

        digester.addSetNext("persons/person/creditcard","addCreditcard");
        digester.addSetNext("persons/person","addPerson");
        Root root;
        try {
            root = (Root)digester.parse(new File("C:\\file3.xml"));
            System.out.println(root);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

    }
}

1、首先生成Digester物件,並且設定不進行dtd校驗
2、addObjectCreate方法是解析標籤,第一個引數是對應於xml的標籤,第二個引數是Java Bean的Class
這個方法會將一個Class放進棧中
3、addSetProperties方法是解析屬性,第一個引數是對應xml的標籤,第二個引數是屬性名,第三個引數是Bean中的變數名。
4、addBeanProperties方法是解析元素,第一個引數是對應元素,第二個引數是Bean中的變數名,當他們相同時,可以省略。
5、addSetNext方法是解析列表,當一個Class解析完,必須呼叫,引數一是對應標籤,引數二有兩種情況,如果有相同的列表,則是add方法,如果沒有,就是set方法,相當於出棧。
6、addCallMethod方法,是直接顯式呼叫bean中的方法,引數一是對應標籤,引數二是bean中方法名,引數三是方法引數個數。當引數三為0時表示,這個方法有一個引數,取值來自這個標籤。當引數三不為0時,要通過addCallParam方法指定引數取值。
addCallParam方法有兩個引數,引數1是對應元素,引數二是指當前元素的值作為第幾個引數傳入addCallMethod方法中。
7、parse方法,傳入解析的xml檔案。