天天看點

Java對象轉換XML檔案:XStream+XPP

不需要生成dtd,無用配置,不需要生成輔助類,速度快。這就是xstream+xpp超強黃金組合。

xstream大家都知道啦,xml pull parser是一種高速的 解析xml檔案的方式,速度要比傳統方式快很多(發現pull式解析現在比較流行了)。下面我給出多種使用方法的例子。

1.最簡單的使用方法

   1.  public static void write() {  

   2.     xstream sm = new xstream();  

   3.     mytest t = new mytest();  

   4.     t.setname("moogle");  

   5.     t.setxb("男");  

   6.     try {  

   7.     fileoutputstream ops = new fileoutputstream(new file("c://111.xml"));  

   8.     sm.toxml(t, ops);  

   9.     ops.close();  

  10.     } catch (exception e) {  

  11.         e.printstacktrace();  

  12.     }  

  13. }     

  14. public static void read() {  

  15.     xstream sm = new xstream(new domdriver());  

  16.     try {  

  17.         fileinputstream ops = new fileinputstream(new file("c://111.xml"));  

  18.         mytest t = (mytest)sm.fromxml(ops);  

  19.         system.out.println(t.getname());  

  20.         ops.close();  

  21.         } catch (exception e) {  

  22.             e.printstacktrace();  

  23.         }         

  24. }

生成 xml是

# <mytest> 

#   <name>asd</name> 

#   <xb>男</xb>

2.中等方法(需要1.2版以上才有這個功能)

xstream stream = new xstream();

stream.alias("schema", schemaobject.class);

stream.useattributefor("url", string.class);

stream.useattributefor("jdbcdriverclass", string.class);

stream.useattributefor("user", string.class);

stream.useattributefor("password", string.class);

fileoutputstream s = new fileoutputstream(file);

stream.toxml(theobject, s);

s.close();

alias和useattributefor是用作把 <com.hongsoft.model.schemaobject>修改為<schema>

3.進階方法

stream.registerconverter(new schemaxmlconvertor());

fileinputstream s = new fileinputstream(file);

object = (schemaobject) stream.fromxml(s);

registerconverter可以實作把任何schema的xml和object互相轉換,這個其實已經否定了很多朋友說的

“xstream+xpp”功能不強的說法。schemaxmlconvertor示例如下:

public void marshal(object arg0, hierarchicalstreamwriter writer,

            marshallingcontext arg2) {

    schemaobject schema=(schemaobject)arg0;       

    writer.startnode(schemaobject.table);

    writer.addattribute(schemaobject.table_name, itable.getname());

    //line           

    list<schemaobject.tableobject.lineobject> lines=itable.getlines();

    for(int j=0;j<lines.size();j++)

    {

        schemaobject.tableobject.lineobject jline=lines.get(j);

        writer.startnode(schemaobject.line);

        //column

        map<string,string> columns=jline.getcolumns();

        iterator ite=columns.keyset().iterator();

        while(ite.hasnext())

        {

            string columnname=ite.next().tostring();

            writer.addattribute(columnname, columns.get(columnname));

        }

        writer.endnode();

        writer.underlyingwriter();

    }

public object unmarshal(hierarchicalstreamreader reader,

            unmarshallingcontext arg1) {

    schemaobject schema=new schemaobject();

    schema.setjdbcdriverclass(reader.getattribute(schemaobject.jdbc_driver_class));

    schema.seturl(reader.getattribute(schemaobject.url));

    schema.setuser(reader.getattribute(schemaobject.user));

    schema.setpassword(reader.getattribute(schemaobject.password));

    list<tableobject> tables = new arraylist<tableobject>();

        while(reader.hasmorechildren()) {

            reader.movedown();

            schemaobject.tableobject table=new schemaobject().new tableobject();

            table.setname(reader.getattribute(schemaobject.table_name));

            tables.add(table);

            reader.moveup();

        schema.settables(tables);       

        return schema;

}

public boolean canconvert(class arg0) {

    return arg0.equals(schemaobject.class);

說明:

1、xstream不要求java類的屬性必須有getter、setter方法,是以省略。

2、設定java成員屬性别名

        xstream.aliasfield("investor-list",mainbody.class,"investorlist");

        outxml(3,xstream,mainbody);

運作結果會産生:

  <investor-list>

3、将java成員映射為xml元素的一個屬性

        //将name成員作為屬性添加到investor對應xml節點裡       

        xstream.useattributefor(investor.class,"name");

            <investor name="hahhah">

下面這兩句是相關聯的:

        xstream.aliasattribute(investor.class,"name","gdxm");

        意思是先為java成員定義個别名,然後在将别名應用于xml屬性上。

            <investor gdxm="hahhah">

這些問題雖然解決了,但又發現了新的問題:xml轉java時,當java中沒有定義xml元素節點時,這時候會抛出異常。也許通過xstream本身的api可以解決,也許是xstream本身所不能處理的問題,時間有限,也沒來得及深究。有知道的朋友,還望留言。

4、再進行xml到java 的轉換過程中,xstream對象别名可以定義很多,涵蓋的類的範圍超過xml所能表達的範圍,這個也沒有關系,xstream還是會忠實地将xml還原為對象。但是如果xml範圍大于xstream所涵蓋類的範圍,那麼轉換過程會出錯。比如,要将一個investor節點轉換為manibody對象,肯定會出錯。