使用XStream是实现XML与Java对象的转换--别名

Posted 俄而123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用XStream是实现XML与Java对象的转换--别名相关的知识,希望对你有一定的参考价值。

五、使用别名(Alias)

首先,有这样一段Java代码:

Java代码  
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.    
  4. import com.thoughtworks.xstream.XStream;  
  5.    
  6. public class XStreamTest2 {  
  7.    public static void main(String[] args) {  
  8.       Blog teamBlog = new Blog(new Author("Guilherme Silveira"));  
  9.         teamBlog.add(new Entry("first","My first blog entry."));  
  10.         teamBlog.add(new Entry("tutorial",  
  11.                 "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));  
  12.    
  13.         XStream xstream = new XStream();  
  14.         System.out.println(xstream.toXML(teamBlog));  
  15.    }  
  16.    
  17. }  
  18. class Blog {  
  19.     private Author writer;  
  20.     private List entries = new ArrayList();  
  21.    
  22.     public Blog(Author writer) {  
  23.             this.writer = writer;  
  24.     }  
  25.    
  26.     public void add(Entry entry) {  
  27.             entries.add(entry);  
  28.     }  
  29.    
  30.     public List getContent() {  
  31.             return entries;  
  32.     }  
  33. }  
  34.    
  35. class Author {  
  36.     private String name;  
  37.     public Author(String name) {  
  38.             this.name = name;  
  39.     }  
  40.     public String getName() {  
  41.             return name;  
  42.     }  
  43. }  
  44.    
  45. class Entry {  
  46.     private String title, description;  
  47.     public Entry(String title, String description) {  
  48.             this.title = title;  
  49.             this.description = description;  
  50.     }  
  51. }  

 

对于上面这段代码,现在我要将一个Blog对象转换成为XML字符串,产生的结果是:

Xml代码  
  1. <cn.tjpu.zhw.xml.Blog>  
  2.   <writer>  
  3.     <name>Guilherme Silveira</name>  
  4.   </writer>  
  5.   <entries>  
  6.     <cn.tjpu.zhw.xml.Entry>  
  7.       <title>first</title>  
  8.       <description>My first blog entry.</description>  
  9.     </cn.tjpu.zhw.xml.Entry>  
  10.     <cn.tjpu.zhw.xml.Entry>  
  11.       <title>tutorial</title>  
  12.       <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  13.     </cn.tjpu.zhw.xml.Entry>  
  14.   </entries>  
  15. </cn.tjpu.zhw.xml.Blog>  

 

但是,我要将一个Blog对象转换成为下面的XML字符串的形式:

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>  

 

该怎么办呢?

这就需要用到别名转换方法了!

下面我们就一步步的调整代码:

1,给类起别名

需求:将节点cn.tjpu.zhw.xml.Blogcn.tjpu.zhw.xml.Entry重命名为blogentry

添加代码:

Java代码  
  1. xstream.alias("blog", Blog.class);  
  2. xstream.alias("entry", Entry.class);  

 

即main方法如下:

Java代码  
  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.    
  7.         XStream xstream = new XStream();  
  8.         xstream.alias("blog", Blog.class);  
  9.         xstream.alias("entry", Entry.class);  
  10.         System.out.println(xstream.toXML(teamBlog));  
  11.    }  

 

运行结果如下:

Xml代码  
  1. <blog>  
  2.   <writer>  
  3.     <name>Guilherme Silveira</name>  
  4.   </writer>  
  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>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  13.     </entry>  
  14.   </entries>  
  15. </blog>  

 

2,给字段其别名

需求:将writer节点重命名为author节点

添加代码:

Java代码  
  1. xstream.aliasField("author", Blog.class, "writer");  

 

即main方法为:

Java代码  
  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.    
  7.         XStream xstream = new XStream();  
  8.         xstream.alias("blog", Blog.class);  
  9.         xstream.alias("entry", Entry.class);  
  10.         xstream.aliasField("author", Blog.class, "writer");  
  11.         System.out.println(xstream.toXML(teamBlog));  
  12.    }  

 

运行结果如下:

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>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  13.     </entry>  
  14.   </entries>  
  15. </blog>  

 

3,使用隐式集合(Implicit Collection)

隐式集合:当你不想将一个集合的根节点呈现出来的时候,它就是一个隐式集合。

数组、Collection、Map都可以成为隐式集合。

需求:隐藏entries节点

添加代码:

Java代码  
  1. xstream.addImplicitCollection(Blog.class, "entries");  

 

则main方法如下:

Java代码  
  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.    
  7.         XStream xstream = new XStream();  
  8.         xstream.alias("blog", Blog.class);  
  9.         xstream.alias("entry", Entry.class);  
  10.         xstream.aliasField("author", Blog.class, "writer");  
  11.         xstream.addImplicitCollection(Blog.class, "entries");  
  12.         System.out.println(xstream.toXML(teamBlog));  
  13.    }  

 

运行结果:

Xml代码  
  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>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  12.   </entry>  
  13. </blog>  

 

4,给XML属性起别名

需求:将writer节点,改成blog节点的authot属性

添加代码:

Java代码  
  1. xstream.useAttributeFor(Blog.class, "writer");  

 

即main方法如下:

   

Java代码  
  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.    
  7.         XStream xstream = new XStream();  
  8.         xstream.alias("blog", Blog.class);  
  9.         xstream.alias("entry", Entry.class);  
  10.         xstream.useAttributeFor(Blog.class, "writer");  
  11.         xstream.aliasField("author", Blog.class, "writer");  
  12.         xstream.addImplicitCollection(Blog.class, "entries");  
  13.         System.out.println(xstream.toXML(teamBlog));  
  14.    }  

 

但是运行的结果却是不是预想的那样:

Xml代码  
  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>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  12.   </entry>  
  13. </blog>  

 

可以看到,运行的结果根本就没有变化,为什么?

因为,还缺少一个转换器,XML节点的属性是一个String字符串,但是Author类不是字符串,这就需要一个转换器将Author对象转换成一个String对象、同时能够将String对象反转换为Author对象:

Java代码  
  1. //定义一个转换器,如果使用,则需要在使用时注册到对应的XStream对象中  
  2. class AuthorConverter implements SingleValueConverter {  
  3.    /*该方法用于从Author对象中提取一个String字符串*/  
  4.     public String toString(Object obj) {  
  5.             return ((Author) obj).getName();  
  6.     }  
  7.     /*该方法用于从一个String字符串生成Author对象*/  
  8.     public Object fromString(String name) {  
  9.             return new Author(name);  
  10.     }  
  11.     /*该方法告诉XStream对象,该转换器可以转换哪种类型的对象*/  
  12.     public boolean canConvert(Class type) {  
  13.             return type.equals(Author.class);  
  14.     }  
  15. }  

 

新的main方法如下:

Java代码  
  1. public class XStreamTest2 {  
  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.    
  8.         XStream xstream = new XStream();  
  9.         xstream.alias("blog", Blog.class);  
  10.         xstream.alias("entry", Entry.class);  
  11.         //设置XML节点的属性  
  12.         xstream.useAttributeFor(Blog.class, "writer");  
  13.         //注册转换器  
  14.         xstream.registerConverter(new AuthorConverter());  
  15.         xstream.aliasField("author", Blog.class, "writer");  
  16.         xstream.addImplicitCollection(Blog.class, "entries");  
  17.         System.out.println(xstream.toXML(teamBlog));  
  18.    }  
  19. }  

 

 

到此为止,运行的结果就会真正的向预期的那样:

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>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  
  9.   </entry>  
  10. </blog>  

 

5,使用包名别名

需求:有时候需要事项不同包里面的相同类名的节点之间的相互映射,这时就需要改变一下包名了

添加代码:

Java代码  
  1. xstream.aliasPackage("org.thoughtworks", "cn.tjpu.zhw.xml");  

 

即更改main方法:

Java代码  
  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.   
  7.      XStream xstream = new XStream();  
  8.      //包名别名  
  9.      xstream.aliasPackage("org.thoughtworks", "cn.tjpu.zhw.xml");  
  10.      System.out.println(xstream.toXML(teamBlog));  
  11. }  

 

运行结果如下:

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

以上是关于使用XStream是实现XML与Java对象的转换--别名的主要内容,如果未能解决你的问题,请参考以下文章

使用XStream是实现XML与Java对象的转换--注解

使用XStream是实现XML与Java对象的转换--Object Stream

使用XStream是实现XML与Java对象的转换--持久化

xml-mapping xml 与 java 对象转换映射框架,像 XStream 一样优雅地读写xml

xml-mapping xml 与 java 对象转换映射框架,像 XStream 一样优雅地读写x

xstream xml转化成java对象