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

来源:互联网 发布:西剑流 知乎 编辑:程序博客网 时间:2024/05/18 01:58

五、使用别名(Alias)

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

    import java.util.ArrayList;      import java.util.List;             import com.thoughtworks.xstream.XStream;             public class XStreamTest2 {         public static void main(String[] args) {            Blog teamBlog = new Blog(new Author("Guilherme Silveira"));              teamBlog.add(new Entry("first","My first blog entry."));              teamBlog.add(new Entry("tutorial",                      "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));                     XStream xstream = new XStream();              System.out.println(xstream.toXML(teamBlog));         }             }      class Blog {          private Author writer;          private List entries = new ArrayList();                 public Blog(Author writer) {                  this.writer = writer;          }                 public void add(Entry entry) {                  entries.add(entry);          }                 public List getContent() {                  return entries;          }      }             class Author {          private String name;          public Author(String name) {                  this.name = name;          }          public String getName() {                  return name;          }      }             class Entry {          private String title, description;          public Entry(String title, String description) {                  this.title = title;                  this.description = description;          }      }  

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

Xml代码

<cn.tjpu.zhw.xml.Blog>    <writer>      <name>Guilherme Silveira</name>    </writer>    <entries>      <cn.tjpu.zhw.xml.Entry>        <title>first</title>        <description>My first blog entry.</description>      </cn.tjpu.zhw.xml.Entry>      <cn.tjpu.zhw.xml.Entry>        <title>tutorial</title>        <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>      </cn.tjpu.zhw.xml.Entry>    </entries>  </cn.tjpu.zhw.xml.Blog>

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

Xml代码
<blog author="Guilherme Silveira">    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>          Today we have developed a nice alias tutorial. Tell your friends! NOW!      </description>    </entry>  </blog>

该怎么办呢?

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

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

1,给类起别名

需求:将节点cn.tjpu.zhw.xml.Blog、cn.tjpu.zhw.xml.Entry重命名为blog和entry

添加代码:

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

即main方法如下:

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

运行结果如下:

Xml代码
<blog>    <writer>      <name>Guilherme Silveira</name>    </writer>    <entries>      <entry>        <title>first</title>        <description>My first blog entry.</description>      </entry>      <entry>        <title>tutorial</title>        <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>      </entry>    </entries>  </blog>

2,给字段其别名

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

添加代码:

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

即main方法为:

Java代码
public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));          teamBlog.add(new Entry("first","My first blog entry."));          teamBlog.add(new Entry("tutorial",                  "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));             XStream xstream = new XStream();          xstream.alias("blog", Blog.class);          xstream.alias("entry", Entry.class);          xstream.aliasField("author", Blog.class, "writer");          System.out.println(xstream.toXML(teamBlog));     } 

运行结果如下:

Xml代码
    <blog>        <author>          <name>Guilherme Silveira</name>        </author>        <entries>          <entry>            <title>first</title>            <description>My first blog entry.</description>          </entry>          <entry>            <title>tutorial</title>            <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>          </entry>        </entries>      </blog>  

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

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

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

需求:隐藏entries节点

添加代码:

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

则main方法如下:

Java代码
public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));          teamBlog.add(new Entry("first","My first blog entry."));          teamBlog.add(new Entry("tutorial",                  "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));             XStream xstream = new XStream();          xstream.alias("blog", Blog.class);          xstream.alias("entry", Entry.class);          xstream.aliasField("author", Blog.class, "writer");          xstream.addImplicitCollection(Blog.class, "entries");          System.out.println(xstream.toXML(teamBlog));     } 

运行结果:

Xml代码
<blog>    <author>      <name>Guilherme Silveira</name>    </author>    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </entry>  </blog>

4,给XML属性起别名

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

添加代码:

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

即main方法如下:

Java代码
public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));          teamBlog.add(new Entry("first","My first blog entry."));          teamBlog.add(new Entry("tutorial",                  "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));             XStream xstream = new XStream();          xstream.alias("blog", Blog.class);          xstream.alias("entry", Entry.class);          xstream.useAttributeFor(Blog.class, "writer");          xstream.aliasField("author", Blog.class, "writer");          xstream.addImplicitCollection(Blog.class, "entries");          System.out.println(xstream.toXML(teamBlog));     }

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

Xml代码
<blog>    <author>      <name>Guilherme Silveira</name>    </author>    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </entry>  </blog>

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

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

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

新的main方法如下:

Java代码
    public class XStreamTest2 {         public static void main(String[] args) {            Blog teamBlog = new Blog(new Author("Guilherme Silveira"));              teamBlog.add(new Entry("first","My first blog entry."));              teamBlog.add(new Entry("tutorial",                      "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));                     XStream xstream = new XStream();              xstream.alias("blog", Blog.class);              xstream.alias("entry", Entry.class);              //设置XML节点的属性              xstream.useAttributeFor(Blog.class, "writer");              //注册转换器              xstream.registerConverter(new AuthorConverter());              xstream.aliasField("author", Blog.class, "writer");              xstream.addImplicitCollection(Blog.class, "entries");              System.out.println(xstream.toXML(teamBlog));         }      }  

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

<blog author="Guilherme Silveira">    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </entry>  </blog>

5,使用包名别名

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

添加代码:

Java代码

xstream.aliasPackage("org.thoughtworks", "cn.tjpu.zhw.xml");

即更改main方法:

Java代码
    public static void main(String[] args) {         Blog teamBlog = new Blog(new Author("Guilherme Silveira"));           teamBlog.add(new Entry("first","My first blog entry."));           teamBlog.add(new Entry("tutorial",                   "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));                 XStream xstream = new XStream();           //包名别名           xstream.aliasPackage("org.thoughtworks", "cn.tjpu.zhw.xml");           System.out.println(xstream.toXML(teamBlog));      }  

运行结果如下:

Xml代码
<org.thoughtworks.Blog>    <writer>      <name>Guilherme Silveira</name>    </writer>    <entries>      <org.thoughtworks.Entry>        <title>first</title>        <description>My first blog entry.</description>      </org.thoughtworks.Entry>      <org.thoughtworks.Entry>        <title>tutorial</title>        <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>      </org.thoughtworks.Entry>    </entries>  </org.thoughtworks.Blog>


阅读全文
0 0