EasyJF 官方网站全面升级,同时EasyJF开源团队也将进行全面改组,期待您给我们提出宝贵的意见及建议!

当前位置:首页-技术前沿-其它开源框架

  • XStream别名指南【翻译】
    作者: stef_wu  来源:easyjf  发布时间:2007-11-19 10:10:00
  • 1,存在的问题
    设想我们的客户端定义了一个用于XStream读写的XML文件:
    我们将设计一些模型类并配置XStream按照这个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>

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

    package com.thoughtworks.xstream;  
    public class Blog { 
            private Author author; 
            private List entries = new ArrayList();  
            public Blog(Author author) { 
                    this.author = author; 
            }  
            public void add(Entry entry) { 
                    entries.add(entry); 
            }  
            public List getContent() { 
                    return entries; 
            } 
    }


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

    package com.thoughtworks.xstream;  
    public class Author { 
            private String name; 
            public Author(String name) { 
                    this.name = name; 
            } 
            public String getName() { 
                    return name; 
            } 
    }

    具体的blog内容对象:

    package com.thoughtworks.xstream;  
    public class Entry { 
            private String title, description; 
            public Entry(String title, String description) { 
                    this.title = title; 
                    this.description = description; 
            } 
    }


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

    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)); 
    }


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

    <com.thoughtworks.xstream.Blog> 
      <author> 
        <name>Guilherme Silveira</name> 
      </author> 
      <entries> 
        <com.thoughtworks.xstream.Entry> 
          <title>first</title> 
          <description>My first blog entry.</description> 
        </com.thoughtworks.xstream.Entry> 
        <com.thoughtworks.xstream.Entry> 
          <title>tutorial</title> 
          <description> 
            Today we have developed a nice alias tutorial. Tell your friends! NOW! 
          </description> 
        </com.thoughtworks.xstream.Entry> 
      </entries> 
    </com.thoughtworks.xstream.Blog>

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

     
    5,去掉entries标记
    下面,我们将实施叫做"implicit collection"的过程(即取消标记):所有的集合类型,都不需要显示他的根标签(root tag),你可以直接使用一个implicit collection去映射。
    在我们的例子里面,我们不希望出现entries标签,只需要一个接一个的列出所有的entry标签即可。
    要做到这点,只需要简单的调用XStream对象上的addImplicitCollection方法,就可以配置XStream取消对entries的输出:
    package com.thoughtworks.xstream; 
    import java.util.ArrayList; 
    import java.util.List; 
    public class Test { 
            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.addImplicitCollection(Blog.class, "entries"); 
                    System.out.println(xstream.toXML(teamBlog)); 
            } 
    }

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

    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:

    public class Test { 
            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.addImplicitCollection(Blog.class, "entries"); 
                    xstream.useAttributeFor(Blog.class, "author"); 
                    xstream.registerConverter(new AuthorConverter()); 
                    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>

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

  • 评论 】 【收藏】 【 推荐给朋友 】 【字体: 】 【关闭
评论:共1条
不错! 很简洁明了! 页界用这个工具用得多吗?
评论人: 匿名用户    评论时间: 2007-11-19 16:48:58

发表评论:
评论: 
    

相关栏目

  • 如何才能得到国外最新的技术
Copyright (C) 2005 EasyJF.com 简易java框架网 渝ICP备06004507号
如有意见请与我们联系