Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add an XML attribute, or not, depending on an Option?

Tags:

xml

scala

I have written a makeMsg function but I don't like it - it just seems really un-Scala-ish to discriminate based on Option.isDefined. Can you make it better?

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>
like image 855
David Avatar asked Jan 24 '11 02:01

David


2 Answers

You can try this:

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

if attribute value is null - it will not be added to the element.

Update

Even better! If you will add this implicit convertion:

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

you can just use t like this:

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

Here is REPL session:

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>

This works because scala.xml.UnprefixedAttribute has constructor that accepts Option[Seq[Node]] as value.

like image 135
tenshi Avatar answered Nov 05 '22 21:11

tenshi


What's wrong with this:

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

Not as concise as Easy Angel's, but it's straight up Scala.

like image 45
sblundy Avatar answered Nov 05 '22 21:11

sblundy