如何根据选项添加XML属性?

时间:2011-01-24 02:07:23

标签: xml scala

我已经编写了一个makeMsg函数,但我不喜欢它 - 它看起来真的非Scala-ish基于Option.isDefined进行区分。你能做得更好吗?

scala> def makeMsg(t: Option[String]) = 
     | if (t.isDefined) <msg text={t.get} /> else <msg />
makeMsg: (t: Option[String])scala.xml.Elem

scala> makeMsg(Some("hello"))
res0: scala.xml.Elem = <msg text="hello"></msg>

scala> makeMsg(None)
res1: scala.xml.Elem = <msg></msg>

3 个答案:

答案 0 :(得分:15)

你可以试试这个:

def makeMsg(t: Option[String]) = <msg text={t orNull} />

如果属性值为null - 则不会将其添加到元素中。

更新

更好!如果你要添加这个隐式转换:

import xml.Text
implicit def optStrToOptText(opt: Option[String]) = opt map Text

您可以像这样使用t

def makeMsg(t: Option[String]) = <msg text={t} />

这是REPL会话:

scala> import xml.Text
import xml.Text

scala> implicit def optStrToOptText(opt: Option[String]) = opt map Text
optStrToOptText: (opt: Option[String])Option[scala.xml.Text]

scala> def makeMsg(t: Option[String]) = <msg text={t} />
makeMsg: (t: Option[String])scala.xml.Elem

scala> makeMsg(Some("hello"))
res1: scala.xml.Elem = <msg text="hello"></msg>

scala> makeMsg(None)
res2: scala.xml.Elem = <msg ></msg>

这是有效的,因为scala.xml.UnprefixedAttribute具有接受Option[Seq[Node]]作为值的构造函数。

答案 1 :(得分:4)

这有什么问题:

def makeMsg(t: Option[String]) = t match {
  case Some(m) => <msg text={m} />
  case None => <msg />
}

不像Easy Angel那样简洁,但它是直接的Scala。

答案 2 :(得分:1)

Canonical Scala,当文本字段为空时,不需要知道它就会巧妙地消失:

t.map(s => <msg text={s} />).getOrElse(<msg />)

只要有选项,您就应该考虑使用此模式,但需要使用不了解选项的内容。 (在这种情况下,Easy Angel找到了一个更紧凑的解决方案,它可以了解选项或类似的东西。)