2012-12-29 42 views
1

我嘗試在scala中使用XStream,但它看起來像XSteam中的註釋不能在scala中工作。在下面的代碼中,只有@XStreamAlias工作,我也附上一個示例輸出,任何人都可以幫助嗎?XStream註釋在scala中不工作

@XStreamAlias("posts") 
case class Posts(
    @XStreamAsAttribute tag: String, 
    @XStreamAsAttribute total: String, 
    @XStreamAsAttribute user: String, 
    @XStreamImplicit(itemFieldName="post") posts: JList[Post]) 

@XStreamAlias("post") 
case class Post(
    @XStreamAsAttribute description: String, 
    @XStreamAsAttribute extended: String, 
    @XStreamAsAttribute hash: String, 
    @XStreamAsAttribute href: String, 
    @XStreamAsAttribute shared: String, 
    @XStreamAsAttribute tag: String, 
    @XStreamAsAttribute time: String) 


<posts> 
    <tag>a</tag> 
    <total>b</total> 
    <user>c</user> 
    <posts> 
    <post> 
     <description></description> 
     <extended></extended> 
     <hash></hash> 
     <href></href> 
     <shared></shared> 
     <tag></tag> 
     <time></time> 
    </post> 
    </posts> 
</posts> 
+0

從你在這裏給出的XML,我不認爲你可以使用'XStreamAsAttribute',但你想'XStreamAsAlias'。 'XStreamAsAttribute'適用於節點定義了屬性的地方,比如''。 –

+0

是的,我想知道我怎樣才能使XStreamAsAttribute註解也可以工作 – zjffdu

+0

然後你可以在'Posts'中將像'tag','total'這樣的元素作爲xml中的屬性。只有當您收到帶有上述屬性的源xml時,這才適用。但是你的示例沒有顯示這一點。 –

回答

1

它看起來像Java註釋不能很好地與斯卡拉玩。 :-)你必須依靠用普通的舊方法語法來設置它。請參閱下面的代碼片段,我查看了他們的API文檔。

import com.thoughtworks.xstream.annotations._ 
import com.thoughtworks.xstream.XStream 
import java.util.{ ArrayList => JList } 

class Posts(
    val tag: String, 
    val total: String, 
    val user: String, 
    val post: JList[Post]) 

class Post(
    val description: String, 
    val extended: String, 
    val hash: String, 
    val href: String, 
    val shared: String, 
    val tag: String, 
    val time: String) 

object Main extends App { 
    val xst = new XStream(); 
    val pp = new JList[Post] 

    val rstv = new Post("a", "b", "c", "d", "e", "f", "g") 
    pp.add(rstv) 
    val postClazz = classOf[Post] 
    val postsClazz = classOf[Posts] 
    val pstv = new Posts("p", "q", "r", pp) 

    xst.useAttributeFor(postsClazz, "tag") 
    xst.useAttributeFor(postsClazz, "total") 
    xst.useAttributeFor(postsClazz, "user") 

    xst.useAttributeFor(postClazz, "description") 
    xst.useAttributeFor(postClazz, "extended") 
    xst.useAttributeFor(postClazz, "hash") 
    xst.useAttributeFor(postClazz, "href") 
    xst.useAttributeFor(postClazz, "shared") 
    xst.useAttributeFor(postClazz, "tag") 
    xst.useAttributeFor(postClazz, "time") 
    val foo = xst.toXML(pstv) 
    println(foo) 
} 

請注意,所有類都必須包含設置爲由XStream查找的字段。有了這個代碼,我得到了以下的輸出:

<Posts tag="p" total="q" user="r"> 
    <post> 
    <Post description="a" extended="b" hash="c" href="d" shared="e" tag="f" time 
="g"/> 
    </post> 
</Posts> 

希望這有助於。

編輯:爲了擴充我上面所說的內容,@XStreamAlias等註釋從編譯的字節碼中完全剝離。這可以通過在這些編譯類上運行javapscalap來看出。這導致我得出結論認爲Java註釋沒有像Scala註釋那樣對待(儘管理想情況下它應該是 - 如果我犯了任何錯誤,可以隨意插入)。會很高興學到一些東西。 :-)

+0

謝謝,這個工程,但很想知道爲什麼註釋不能在scala工作 – zjffdu

+0

我不知道,但這[SO帖子](http://stackoverflow.com/questions/11853878/getannotations-on-scala-班級領域)可能會幫助你解決這個問題。 –

0

這是一個老問題,但我最近有一個類似的問題,我想添加我的解決方案,以備將來參考其他人。

我想用一個案例類和@XStreamAlias及其字段,並根據案件類註釋從字符串反序列化的XML:

import com.thoughtworks.xstream.XStream 
import com.thoughtworks.xstream.annotations.XStreamAlias 
import com.thoughtworks.xstream.io.xml.DomDriver 

@XStreamAlias("TOP") 
case class example(
        @XStreamAlias("SUB") 
        val param : String) { 

} 

val xs = new XStream(new DomDriver()) 
xs.setClassLoader(getClass.getClassLoader) 
xs.processAnnotations(example.getClass) 

//OK 
xs.fromXML(<TOP><param>x</param></TOP>.toString()) 

//Error - No such field sub 
xs.fromXML(<TOP><SUB>x</SUB></TOP>.toString()) 

的問題是,註釋不工作爲班級領域。 搜索了一下後,我發現scala生成了一個類字段的多個訪問器(參見scala.annotation.meta),但默認情況下,註釋僅應用於構造函數參數,而不應用於所有訪問器。

要獲得應用於該字段的註釋(規範/庫對這些概念不明確,所以我將假定它僅適用於字段而不適用於訪問器),您可以使用@(XStreamAlias @field)("SUB")。這解決了我的問題:

@XStreamAlias("TOP") 
case class example2 (
        @(XStreamAlias @scala.annotation.meta.field)("SUB") 
        val param : String) { 

} 
val xs2 = new XStream(new DomDriver()) 
xs2.setClassLoader(getClass.getClassLoader) 
xs2.processAnnotations(example.getClass) 

//OK 
val obj = xs2.fromXML(<TOP><SUB>x</SUB></TOP>.toString()).asInstanceOf[example2] 

print(obj) 
//> example2(x)