在Scala中处理可选的xml属性

Ral*_*lph 7 scala option xml-parsing

我有读取XML文件的代码.我需要处理的元素的一些属性是可选的.我正在尝试使用Option [T]来管理它们.我已经写了以下内容来pimp \Node运算符返回的NodeSeq类型:

class NodeSeqWrapper(nodeSeq: NodeSeq) {
  def textOption: Option[String] = {
    val text = nodeSeq.text
    if (text == null || text.length == 0) None else Some(text)
  }
}
implicit def nodeSeqWrapper(nodeSeq: NodeSeq): NodeSeqWrapper =
  new NodeSeqWrapper(nodeSeq)
Run Code Online (Sandbox Code Playgroud)

然后像这样调用它:

(node \ "@attr").textOption.getOrElse("Some default value")
Run Code Online (Sandbox Code Playgroud)

如果节点具有"attr"属性,则此代码获取其值.如果没有,则返回值"Some default value".

我怎样才能改善这个?有没有办法将类定义折叠到隐式方法中?有没有更好的方法来获取"可选"属性值?我使用Option[T]"正确"吗?

Phi*_*ppe 5

我会说你是以一种非常惯用的方式做到的,是的.

您可以"折叠定义",如下所示:

implicit def enrichNodeSeq(nodeSeq: NodeSeq) = new AnyRef {
  def textOption : Option[String] = {
    val text = nodeSeq.text
    if (text == null || text.length == 0) None else Some(text)
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您始终在申请.getOrElse(...)结果,您可能还想定义第二个版本textOrElse(elze : String) : String:

implicit def enrichNodeSeq(nodeSeq: NodeSeq) = new AnyRef {
  def textOption : Option[String] = {
    val text = nodeSeq.text
    if (text == null || text.length == 0) None else Some(text)
  }

  def textOrElse(elze : String) : String = textOption.getOrElse(elze)
}
Run Code Online (Sandbox Code Playgroud)

这将使事情略微简洁.

scala> (<b>Hello</b> : NodeSeq).textOrElse("No text found.")
resN: String = Hello
scala> (<br /> : NodeSeq).textOrElse("No text found.")
resM: String = No text found.
Run Code Online (Sandbox Code Playgroud)

  • 请注意,"折叠定义"会导致每次调用额外方法时都使用Java反射.声明额外的课程没有. (2认同)