在Scala中解析替代XML文本

时间:2014-10-08 03:28:32

标签: xml scala

我在Scala工作,需要区分代表成功或失败的XML消息。我发现的信息为拆开已知的XML片段提供了很多见解,但不是你不确定你所拥有的片段的地方。

以下是两条可能的消息:

val success = XML.loadString("""<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
                <cas:authenticationSuccess>
                   <cas:user>bwbecker</cas:user>
                </cas:authenticationSuccess>
              </cas:serviceResponse>""")

val failure = XML.loadString("""<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
                <cas:authenticationFailure code='INVALID_REQUEST'>
                  &#039;service&#039; and &#039;ticket&#039; parameters are both required
                </cas:authenticationFailure>
              </cas:serviceResponse>""")

下面的代码做了我想要的(我最终将返回一个案例类,但这对于播放来说很好......):

def parse(response: NodeSeq):Either[String, String] = {

(response \ "authenticationSuccess").headOption
  .flatMap(succ => (succ \ "user").headOption)
  .map(usr => Right(usr.text))
  .getOrElse((response \ "authenticationFailure").headOption
    .map{fail => 
        val code = fail \ "@code"
        val msg = fail.text
        Left(s"Failure: ${code} ${msg}")
    }
    .getOrElse(Left("Really Botched"))
  )
}

然而,我觉得这很难编码和阅读。有没有更好的办法?如果我要区分五种不同的消息怎么办?

我尝试过匹配器,但对XML的神秘语法感到气馁(cas:命名空间似乎使事情变得复杂)。

有关改进我的代码的任何指导吗?

1 个答案:

答案 0 :(得分:0)

这就是我要去的地方:

def parse(response: NodeSeq):Either[String, String] = {
    response \\ "user" match {
        case ns if !ns.isEmpty => Right(ns.text)
        case ns => response \\ "authenticationFailure" match {
            case ns if !ns.isEmpty => 
                val code = ns \ "@code"
                val msg = ns.text.trim
                Left(s"Failure: ${code} ${msg}")
            case ns => Left("Unexpected response from CAS: " + response.toString)
        }
    }
}

它使用\来搜索树而不是我使用的原始解决方案(同样的技术也可以简化我的原始解决方案)。显然,它也使用匹配语句。我认为匹配语句使结果比原始解决方案更易读,更容易开发。但也许我只是在展示我的命令根源!