注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 可扩展、高可用、负载均衡..
 帮助

XStream定制转换


2008-05-21 15:43:33
 标签:XStream   [推送到技术圈]

版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。
XStream定制转换
 
XStream在实现Java、xml之间转换非常的出色。但也有一些问题需要解决:Java到XML,默认转换过去就使用Java成员属性的名字作为xml Element名,反过来亦如此。但这些都是不是实际中我们所要的结果。
 
为此,我又研读了XStream的文档,终于解决了这个问题,下面是测试代码。
 
package test;

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

/**
* Created by IntelliJ IDEA.<br>
* <b>User</b>: leizhimin<br>
* <b>Date</b>: 2008-5-21 10:48:43<br>
* <b>Note</b>: 主体信息
*/

public class MainBody {
    private int id;
    private String name;
    private List<Investor> investorList = new ArrayList<Investor>();

    public MainBody(int id, String name, List<Investor> investorList) {
        this.id = id;
        this.name = name;
        this.investorList = investorList;
    }


    public String toString() {
        return "MainBody{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", investorList=" + investorList +
                '}';
    }
}
 
package test;

/**
* Created by IntelliJ IDEA.<br>
* <b>User</b>: leizhimin<br>
* <b>Date</b>: 2008-5-21 10:51:08<br>
* <b>Note</b>: 投资人
*/

public class Investor {
    private int id;
    private String name;
    private int age;

    public Investor(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Investor(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "Investor{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}
 
package test;

import com.thoughtworks.xstream.XStream;

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

/**
* Created by IntelliJ IDEA.<br>
* <b>User</b>: leizhimin<br>
* <b>Date</b>: 2008-5-21 10:54:05<br>
* <b>Note</b>: 测试
*/

public class TestConvert {

    public static void main(String args[]) {
        test();
    }

    public static void test() {
        System.out.println("----------test()----------");
        Investor investor1 = new Investor(1, "gaici");
        Investor investor2 = new Investor(2, "hahhah", 33);
        List<Investor> investorList = new ArrayList<Investor>();
        investorList.add(investor1);
        investorList.add(investor2);
        MainBody mainBody = new MainBody(1000, "微软", investorList);

        XStream xStream = new XStream();

        /************** 别名定义 Object -> xml ***************/

        //没有做任何别名定义直接转换
        outXML(1, xStream, mainBody);

        //类别名
        xStream.alias("MainBody", test.MainBody.class);
        xStream.alias("Investor", test.Investor.class);
        outXML(2, xStream, mainBody);

        //列表节点别名
        xStream.aliasField("Investor-List", MainBody.class, "investorList");
        outXML(3, xStream, mainBody);

        //一般属性节点别名
        xStream.aliasField("ztbs", test.MainBody.class, "id");
        xStream.aliasField("gdbs", test.Investor.class, "id");
        outXML(4, xStream, mainBody);

        //将name成员作为属性添加到Investor对应xml节点里
//        xStream.aliasAttribute(Investor.class,"name","GDXM");
        xStream.useAttributeFor(Investor.class, "name");
        outXML(5, xStream, mainBody);

        xStream.aliasAttribute(Investor.class, "age", "NL");
        xStream.useAttributeFor(Investor.class, "age");
        outXML(6, xStream, mainBody);

        /***********************xml -> Object*************************/
        String newxml = "<MainBody>\n" +
                "  <ztbs>1000</ztbs>\n" +
                "  <name>微软</name>\n" +
                "  <Investor-List>\n" +
                "    <Investor name=\"gaici\" NL=\"0\">\n" +
                "      <gdbs>1</gdbs>\n" +
                "    </Investor>\n" +
                "    <Investor name=\"hahhah\" NL=\"33\">\n" +
                "      <gdbs>2</gdbs>\n" +
                "    </Investor>\n" +
                "  </Investor-List>\n" +
                "</MainBody>";
        MainBody m = (MainBody) xStream.fromXML(newxml);
        System.out.println("将最后一次所得的xml结果转换为Java对象输出:");
        System.out.println(m);
    }

    public static void outXML(int index, XStream xStream, MainBody m) {
        String xml = xStream.toXML(m);
        System.out.println(">>>>>>>>>>第" + index + "次输出XML:");
        System.out.println(xml + "\n");
    }
}
 
运行结果:
----------test()----------
>>>>>>>>>>第1次输出XML:
<test.MainBody>
  <id>1000</id>
  <name>微软</name>
  <investorList>
    <test.Investor>
      <id>1</id>
      <name>gaici</name>
      <age>0</age>
    </test.Investor>
    <test.Investor>
      <id>2</id>
      <name>hahhah</name>
      <age>33</age>
    </test.Investor>
  </investorList>
</test.MainBody>

>>>>>>>>>>第2次输出XML:
<MainBody>
  <id>1000</id>
  <name>微软</name>
  <investorList>
    <Investor>
      <id>1</id>
      <name>gaici</name>
      <age>0</age>
    </Investor>
    <Investor>
      <id>2</id>
      <name>hahhah</name>
      <age>33</age>
    </Investor>
  </investorList>
</MainBody>

>>>>>>>>>>第3次输出XML:
<MainBody>
  <id>1000</id>
  <name>微软</name>
  <Investor-List>
    <Investor>
      <id>1</id>
      <name>gaici</name>
      <age>0</age>
    </Investor>
    <Investor>
      <id>2</id>
      <name>hahhah</name>
      <age>33</age>
    </Investor>
  </Investor-List>
</MainBody>

>>>>>>>>>>第4次输出XML:
<MainBody>
  <ztbs>1000</ztbs>
  <name>微软</name>
  <Investor-List>
    <Investor>
      <gdbs>1</gdbs>
      <name>gaici</name>
      <age>0</age>
    </Investor>
    <Investor>
      <gdbs>2</gdbs>
      <name>hahhah</name>
      <age>33</age>
    </Investor>
  </Investor-List>
</MainBody>

>>>>>>>>>>第5次输出XML:
<MainBody>
  <ztbs>1000</ztbs>
  <name>微软</name>
  <Investor-List>
    <Investor name="gaici">
      <gdbs>1</gdbs>
      <age>0</age>
    </Investor>
    <Investor name="hahhah">
      <gdbs>2</gdbs>
      <age>33</age>
    </Investor>
  </Investor-List>
</MainBody>

>>>>>>>>>>第6次输出XML:
<MainBody>
  <ztbs>1000</ztbs>
  <name>微软</name>
  <Investor-List>
    <Investor name="gaici" NL="0">
      <gdbs>1</gdbs>
    </Investor>
    <Investor name="hahhah" NL="33">
      <gdbs>2</gdbs>
    </Investor>
  </Investor-List>
</MainBody>

将最后一次所得的xml结果转换为Java对象输出:
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='33'}]}

Process finished with exit code 0
 
还有一个测试:
 
 
运行结果:
----------test()----------
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='0'}]}
Investor{id=1, name='gaici', age='0'}
Investor{id=2, name='hahhah', age='0'}
Investor{id=2, name='hahhah', age='0'}

Process finished with exit code 0
 
 
说明:
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");
        xStream.useAttributeFor(Investor.class,"name");
        意思是先为java成员定义个别名,然后在将别名应用于xml属性上。
 
运行结果会产生:
            <Investor GDXM="hahhah">
 
这些问题虽然解决了,但又发现了新的问题:xml转java时,当java中没有定义xml元素节点时,这时候会抛出异常。也许通过XStream本身的API可以解决,也许是XStream本身所不能处理的问题,时间有限,也没来得及深究。有知道的朋友,还望留言。
 
4、再进行xml到java 的转换过程中,XStream对象别名可以定义很多,涵盖的类的范围超过xml所能表达的范围,这个也没有关系,XStream还是会忠实地将xml还原为对象。但是如果xml范围大于XStream所涵盖类的范围,那么转换过程会出错。比如,要将一个Investor节点转换为ManiBody对象,肯定会出错。
 

本文出自 “熔 岩” 博客,转载请与作者联系!





    文章评论
 
2008-05-22 10:16:53
XStream很出色 但是也有很多需要注意的地方 毕竟想要完全转换也不是件容易的事

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: