五、使用别名(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字符串,产生的结果是:
<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字符串的形式:
<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
添加代码:
xstream.alias("blog", Blog.class);
xstream.alias("entry", Entry.class);
即main方法如下:
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));
}
运行结果如下:
<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节点
添加代码:
xstream.aliasField("author", Blog.class, "writer");
即main方法为:
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));
}
运行结果如下:
<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节点
添加代码:
xstream.addImplicitCollection(Blog.class, "entries");
则main方法如下:
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));
}
运行结果:
<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属性
添加代码:
xstream.useAttributeFor(Blog.class, "writer");
即main方法如下:
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));
}
但是运行的结果却是不是预想的那样:
<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对象:
//定义一个转换器,如果使用,则需要在使用时注册到对应的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方法如下:
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));
}
}
到此为止,运行的结果就会真正的向预期的那样:
<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,使用包名别名
需求:有时候需要事项不同包里面的相同类名的节点之间的相互映射,这时就需要改变一下包名了
添加代码:
xstream.aliasPackage("org.thoughtworks", "cn.tjpu.zhw.xml");
即更改main方法:
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));
}
运行结果如下:
<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>