如何将Array [Node]转换为NodeSeq?

时间:2010-10-28 20:56:18

标签: scala scala-2.8 lift

我正在尝试将Lift应用程序集成到一些现有的Java代码中。在我的一个片段中,我有一个Java对象Array,我需要将它映射到NodeSeq。我可以获得一个节点数组,但不能获得NodeSeq。 (至少,不是以非常实用的方式)。

import scala.xml.NodeSeq

// pretend this is code I can't do anything about
val data = Array("one", "two", "three")

// this is the function I need to write
def foo: NodeSeq = data.map { s => <x>{s}</x> }
//                          ^
// error: type mismatch;
//  found   : Array[scala.xml.Elem]
//  required: scala.xml.NodeSeq

最干净的方法是什么?

3 个答案:

答案 0 :(得分:10)

scala> import collection.breakOut
import collection.breakOut

scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq

方法图实际上有两个参数列表。第一个接受您传递的函数。第二个接受CanBuildFrom对象,该对象用于创建构建器,然后构建返回序列。这个参数是隐含的,所以通常编译器会为你填充它。它接受3种类型参数:From,T,To。有几个pref implicits(包括在对象NodeSeq中),但它们都不匹配From = Array,T = Node,To = NodeSeq。

breakOut解决了这个问题:它是一个泛型方法,它通过搜索隐式CanBuildFrom [Nothing,T,To]来返回CanBuildFrom实例。根据隐式搜索规则,任何匹配T,To和具有From&gt;的CanBuildFrom。什么都不能接受。在这种情况下:对象数组中的canBuildFrom

答案 1 :(得分:8)

我只是将map输出转换为序列(假设Seq[Node]是超级类NodeSeq

scala> def foo: NodeSeq = data.map { s => <x>{s}</x> } toSeq
foo: scala.xml.NodeSeq

或使用foldLeft代替map

scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq

答案 2 :(得分:2)

您正在NodeSeq配套对象上寻找此方法。

NodeSeq.fromSeq(s: Seq[Node])