2013-12-19 166 views
1

我想從一些嵌套的scala類型生成一些XML,例如編譯錯誤,嵌套的XML解析

class Inner(val n:String) 

class Outer(val n:String, val i:Seq[Inner]) 

給出Outer(1,[2,3]),我要生成<root><item>1</item><item>2</item><item>3</item></root>(注意,內部件值不嵌套元件,外表面在XML)。我有此代碼

object Xmlizer { 

    def main(args: Array[String]) { 
     val outers = (1 to 2).map(o => new Outer("outer" + o, List(new Inner("i")))) 

     val root = <root> 
        { outers.map(o => <item>{o.n}</item> { o.i.map (i => <item>{i.n}</item>) }) } 
       </root> 

     println(root) 
    } 
} 

這產生一個編譯器錯誤

error: overloaded method value apply with alternatives: 
    (f: scala.xml.Node => Boolean)scala.xml.NodeSeq <and> 
    (i: Int)scala.xml.Node 
cannot be applied to (Seq[scala.xml.Elem]) 
        { outers.map(o => <item>{o.n}</item> { o.i.map (i => <item>{i.n}</item>) }) } 

我有嵌套推導工作,其中嵌套循環是一對元件內,並且如果我簡化到一個理解這樣的作品,例如

val root = <root> 
      { outers.map(o => <item>{o.n}</item><item>{o.i.head.n}</item>) } 
     </root> 

所以它不是像{}需要返回一個容器元素,但是當我擴大內是另一個理解它給人的編譯錯誤。有沒有一些技巧可以讓這個工作,或者我需要以某種方式將scala數據首先變成單個列表?

回答

1

您應該創建項目的扁平集合:

<root> 
    { outers.flatMap(o => <item>{o.n}</item> +: o.i.map{ i => <item>{i.n}</item> }) } 
</root> 
// <root><item>outer1</item><item>i</item><item>outer2</item><item>i</item></root> 

隨着<item>{o.n}</item><item>{o.i.head.n}</item>要創建同一類型的兩個對象的組合,編譯器足夠聰明來創建它。

但這代碼:

<item>{o.n}</item> { o.i.map (i => <item>{i.n}</item>) } 

實際上是這樣的:

<item>{o.n}</item>{Seq(<item>{o.i.head.n}</item>)} 

您正在嘗試完全不同類型的對象2相結合。你應該告訴編譯器如何結合NodeSeq[Node]

<item>{o.n}</item> +: o.i.map (i => <item>{i.n}</item>)