1. 程式人生 > >使用XStream是實現XML與Java物件的轉換(2)--別名

使用XStream是實現XML與Java物件的轉換(2)--別名

五、使用別名(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>