2011-12-19 70 views
8

我有一个字符串列表,我需要将它们和< br />标签一起加入到它们之间。因此,从开始:在scala之间加入XML节点的字符串

val list = List("line1", "line2", "line3") 

我需要的NodeSeq落得:

line1<br/>line2<br/>line3 

这是可能的列表中仅包含一个元素,在这种情况下,我应该用NodeSeq只是文字的结束( “LINE1”)。

有没有一个单线程来做到这一点,使用列表中的一个高阶函数?我试着玩foldErft,但似乎无法让它做我想做的事。

回答

12
list.map(scala.xml.Text(_):scala.xml.NodeSeq).reduce(_ ++ <br /> ++ _) 

请注意,我们必须拓宽类型scala.xml.NodeSeq手动为Text是过于严格的reduce方法。更简洁

list.map(scala.xml.Text).reduce(_ ++ <br /> ++ _) 

将不会编译。

+0

也许我错过了一些东西,但我收到“减少”编译错误,说该方法没有在列表中找到。我需要使用reduceLeft或reduceRight,是否正确? – user1106210 2011-12-19 16:58:23

+0

嗯,适合我。你在使用2.9.1吗? – Debilski 2011-12-19 17:17:12

+0

啊,这就是为什么。我在机器上的一个随机项目中启动了控制台,结果是2.8.1。 – user1106210 2011-12-19 17:42:48

3

如果你不介意使用Scalaz,有intersperse

import scalaz._ 
import Scalaz._ 

list.map(xml.Text(_): xml.Node).intersperse(<br/>): xml.NodeSeq 
0

同意什么Debilski已经回答了。达到相同的另一种方式是,

import scala.xml._

XML.loadString("<root>" + list.mkString("<br/>") + "</root>").child:NodeSeq

但使用的map/reduce是一个更清洁的方式。

+0

对于无效输入(比如'List(“<”)'),这个问题非常严重。 – Debilski 2011-12-19 16:56:35

+1

我没有提到它的问题,但这是unsanitized输入。你的方法是有效的,但是如果列表包含像“asdf”这样的字符串,它们会被解析而不是显示出来,从而使Web应用程序可以被攻击。 – user1106210 2011-12-19 16:57:33