XStream别名指南

  1,存在的问题
设想我们的客户端定义了一个用于XStream读写的XML文件:
我们将设计一些模型类并配置XStream按照这个XML文件格式执行读写操作。

  1. <blog author="Guilherme Silveira">    
  2.   <entry>    
  3.     <title>first</title>    
  4.     <description>My first blog entry.</description>    
  5.   </entry>    
  6.   <entry>    
  7.     <title>tutorial</title>    
  8.     <description>    
  9.         Today we have developed a nice alias tutorial. Tell your friends! NOW!    
  10.     </description>    
  11.   </entry>    
  12. </blog>  



  2,模型:
首先,建立一个简单的Blog对象:

  1. package com.thoughtworks.xstream;     
  2. public class Blog {    
  3.         private Author author;    
  4.         private List entries = new ArrayList();     
  5.         public Blog(Author author) {    
  6.                 this.author = author;    
  7.         }     
  8.         public void add(Entry entry) {    
  9.                 entries.add(entry);    
  10.         }     
  11.         public List getContent() {    
  12.                 return entries;    
  13.         }    
  14. }  



然后是一个带有名字的作者对象:

  1. package com.thoughtworks.xstream;     
  2. public class Author {    
  3.         private String name;    
  4.         public Author(String name) {    
  5.                 this.name = name;    
  6.         }    
  7.         public String getName() {    
  8.                 return name;    
  9.         }    
  10. }  


具体的blog内容对象:

  1. package com.thoughtworks.xstream;     
  2. public class Entry {    
  3.         private String title, description;    
  4.         public Entry(String title, String description) {    
  5.                 this.title = title;    
  6.                 this.description = description;    
  7.         }    
  8. }  



虽然我们没有创建getters/setters方法,但这并不影响XStream对XML->Object文件的解析。
  3,简单的测试
首先初始化一个blog实例,然后使用XStream来序列化

  1. public static void main(String[] args) {     
  2.         Blog teamBlog = new Blog(new Author("Guilherme Silveira"));    
  3.         teamBlog.add(new Entry("first","My first blog entry."));    
  4.         teamBlog.add(new Entry("tutorial",    
  5.                 "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));    
  6.         XStream xstream = new XStream();    
  7.         System.out.println(xstream.toXML(teamBlog));    
  8. }  



由该Blog实例解析出的XML文件为:

  1. <com.thoughtworks.xstream.Blog>    
  2.   <author>    
  3.     <name>Guilherme Silveira</name>    
  4.   </author>    
  5.   <entries>    
  6.     <com.thoughtworks.xstream.Entry>    
  7.       <title>first</title>    
  8.       <description>My first blog entry.</description>    
  9.     </com.thoughtworks.xstream.Entry>    
  10.     <com.thoughtworks.xstream.Entry>    
  11.       <title>tutorial</title>    
  12.       <description>    
  13.         Today we have developed a nice alias tutorial. Tell your friends! NOW!    
  14.       </description>    
  15.     </com.thoughtworks.xstream.Entry>    
  16.   </entries>    
  17. </com.thoughtworks.xstream.Blog>  



  4,为类取别名首先我们来改变XStream对com.thoughtworks.xstream.Blog的输出名称。
我们只想使用一个简单的blog来取代。下面为Blog类创建一个别名:Xstream.alias("blog",Blog.class);同样的,为Entry类创建一个别名:Xstream.alias("entry",Entry.class);好,到此输出的XML变为:

  1. <blog>    
  2.   <author>    
  3.     <name>Guilherme Silveira</name>    
  4.   </author>    
  5.   <entries>    
  6.     <entry>    
  7.       <title>first</title>    
  8.       <description>My first blog entry.</description>    
  9.     </entry>    
  10.     <entry>    
  11.       <title>tutorial</title>    
  12.       <description>    
  13.         Today we have developed a nice alias tutorial. Tell your friends! NOW!    
  14.       </description>    
  15.     </entry>    
  16.   </entries>    
  17. </blog>  




  5,去掉entries标记
下面,我们将实施叫做"implicit collection"的过程(即取消标记):所有的集合类型,都不需要显示他的根标签(root tag),你可以直接使用一个implicit collection去映射。
在我们的例子里面,我们不希望出现entries标签,只需要一个接一个的列出所有的entry标签即可。
要做到这点,只需要简单的调用XStream对象上的addImplicitCollection方法,就可以配置XStream取消对entries的输出:

  1. package com.thoughtworks.xstream;    
  2. import java.util.ArrayList;    
  3. import java.util.List;    
  4. public class Test {    
  5.         public static void main(String[] args) {    
  6.                 Blog teamBlog = new Blog(new Author("Guilherme Silveira"));    
  7.                 teamBlog.add(new Entry("first","My first blog entry."));    
  8.                 teamBlog.add(new Entry("tutorial",    
  9.                         "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));    
  10.                 XStream xstream = new XStream();    
  11.                 xstream.alias("blog", Blog.class);    
  12.                 xstream.alias("entry", Entry.class);    
  13.                 xstream.addImplicitCollection(Blog.class"entries");    
  14.                 System.out.println(xstream.toXML(teamBlog));    
  15.         }    
  16. }  



注意addImplicitCollection方法的调用,需要描述在某个类上的某个成员变量不需要被显示。
得到的结果基本上达到了要求:

  1. <blog>    
  2.   <author>    
  3.     <name>Guilherme Silveira</name>    
  4.   </author>    
  5.   <entry>    
  6.     <title>first</title>    
  7.     <description>My first blog entry.</description>    
  8.   </entry>    
  9.   <entry>    
  10.     <title>tutorial</title>    
  11.     <description>    
  12.         Today we have developed a nice alias tutorial. Tell your friends! NOW!    
  13.     </description>    
  14.   </entry>    
  15. </blog>  



  7,为属性添加别名
下一步是要把author成员变量设置为XML的属性。要做到这点,我们需要告诉XStream将author属性作为Blog类的"author"属性。
xstream.useAttributeFor(Blog.class,"author");
现在留给我们一个问题,XStream怎么讲一个Author转换成一个String对象让他在Blog节点中以author属性显示?
只需要使用SimpleValeConverter并且实现我们自己的Author转换器:
class AuthorConverter implements SingleValueConverter {
}
第一个需要实现的方法是告诉XStream该转化器是用来转换什么类型的对象:
public boolean canConvert(Class type) {
return type.equals(Author.class);
}
接下来是将一个Author实例转化成字符串:
public String toString(Object obj) {
return ((Author) obj).getName();
}
最后是相反的工作:怎么从一个字符串中得到Author实例
public Object fromString(String name) {
return new Author(name);
}
最后,该转化器看起来是这样:
class AuthorConverter implements SingleValueConverter {
public String toString(Object obj) {
return ((Author) obj).getName();
}
public Object fromString(String name) {
return new Author(name);
}
public boolean canConvert(Class type) {
return type.equals(Author.class);
}
}
然后将这个转化器注册到XStream:

  1. public class Test {    
  2.         public static void main(String[] args) {    
  3.                 Blog teamBlog = new Blog(new Author("Guilherme Silveira"));    
  4.                 teamBlog.add(new Entry("first","My first blog entry."));    
  5.                 teamBlog.add(new Entry("tutorial",    
  6.                         "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));    
  7.                 XStream xstream = new XStream();    
  8.                 xstream.alias("blog", Blog.class);    
  9.                 xstream.alias("entry", Entry.class);    
  10.                 xstream.addImplicitCollection(Blog.class"entries");    
  11.                 xstream.useAttributeFor(Blog.class"author");    
  12.                 xstream.registerConverter(new AuthorConverter());    
  13.                 System.out.println(xstream.toXML(teamBlog));    
  14.         }    
  15. }  

最后的输出:

  1. <blog author="Guilherme Silveira">    
  2.   <entry>    
  3.     <title>first</title>    
  4.     <description>My first blog entry.</description>    
  5.   </entry>    
  6.   <entry>    
  7.     <title>tutorial</title>    
  8.     <description>    
  9.         Today we have developed a nice alias tutorial. Tell your friends! NOW!    
  10.     </description>    
  11.   </entry>    
  12. </blog>  



在这里,useAttributeFor方法被其他几个相似功能的方法重载,包括一个接受一个额外的字符串(Class , String, String)的版本,该版本告诉XStream将该属性创建为另一个别名,比如在这里,如果使用useAttributeFor(Blog.class , "author", "auth")会将"author"属性在XML中映射成"auth"属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值