使用嵌套的xml理解编译错误

时间:2013-12-19 03:09:01

标签: xml scala

我正在尝试从一些嵌套的scala类型生成一些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>(请注意,Inners值不嵌套在xml中的Outers元素内)。我有这个代码

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>

因此它不像{}需要返回单个容器元素,但当我将Inner扩展为另一个理解时,它会给编译器错误。是否有一些技巧可以使这个工作,或者我是否需要以某种方式将scala数据首先扁平化为单个列表?

1 个答案:

答案 0 :(得分: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>)