如何在scala中加载xml文件并启用数据绑定

时间:2012-04-17 15:45:33

标签: xml scala

假设我的xml文件包含如下内容:

<example name={name}/>

是否可以从Scala加载此文件并将{name}替换为作用域中名称的值?

类似于XML.loadFile,但它以与Scala的XML文字相同的方式进行数据绑定。

请注意,更复杂的示例也应该有用,例如

<example name={name}>
   {for (hobby <- hobbies) yield <hobby>{hobby}</hobby>}
</example>

2 个答案:

答案 0 :(得分:3)

这会足够吗?

import scala.collection.mutable
import scala.util.matching.Regex.Groups
import scala.xml.XML

type Data = mutable.Map[Symbol, Any]

object Data {
  def empty = mutable.Map.empty[Symbol, Any]
}

class Assignment(identifier: Symbol, data: Data) {
  def :=(value: Any) {
    data(identifier) = value
  }
}

implicit def symbol2assignment(id: Symbol)(implicit data: Data) =
  new Assignment(id, data)

def bind(template: String)(implicit data: Data) = {
  val attributes = """=\{([^{}]+)}""".r
    .replaceAllIn((_: String), _ match {
      case Groups(identifier) =>
        "=\"%s\"".format(data(Symbol(identifier)))
    })
  val rest = """\{([^{}]+)}""".r
    .replaceAllIn((_: String), _ match {
      case Groups(identifier) =>
        data(Symbol(identifier)).toString
    })
  (attributes andThen rest andThen XML.loadString)(template)
}

implicit val data = Data.empty

'name := "bob"
'text := "hi there"

val bound = bind("<ex name={name}>{text}</ex>")
assert(bound == <ex name="bob">hi there</ex>)

答案 1 :(得分:1)

object XmlBinder {

  // "twitter" at "http://maven.twttr.com"
  // "com.twitter" %% "util-eval" % "3.0.0"
  import com.twitter.util.Eval
  import scala.xml.Elem

  private val template =
    """|<example name={name}>
       |  {for (hobby <- hobbies) yield <hobby>{hobby}</hobby>}
       |</example>""".stripMargin

  val name = "name"
  val hobbies = List("hobby 1", "hobby 2")

  def bind(): Elem = new Eval()("import XmlBinder._\n" + template)
}