微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xml – 无法选择正确的组合子进行解析并在Scala中处理它

我有这个涉及 scala的Parsers类的代码

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
            ElemName(Some("http://someUri/"),"someNode1") ~       //compiles well,but fails sometimes at runtime
            ElemName(Some("http://someUri/"),"someNode2") ^^
            {
              case p1 ~ p2 ⇒  //......
            }) ^^
            {
              case p1 ⇒  // ....
            })
  }
}

哪里

case class ElemName(namespace: Option[String],name: String) {
   // .....
}

通常,“someNode1”和“someNode2”都存在于输入soap字符串中(此处未指定,但无关紧要).但是,有时它们中的任何一个可能存在,甚至都不存在,并且在这种情况下它会在运行时崩溃.

<items>
  <subItems>
    <someNode1 val1="123" val2="456" />
    <someNode1 val1="123a" val2="456c" />
    <someNode1 val1="123b" val2="456d" />
    <someNode2 val1="123" val2="456" />
  </subItems>
  <subItems>
    <someNode2 val1="123cd" val2="456de" />
  </subItems>
  <subItems>
  </subItems>
  <subItems>
    <someNode1 val1="777" val2="888" />
  </subItems>
<items>

我必须处理这件事.所以我做了:

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
      ElemName(Some("http://someUri/"),"someNode1") |          // should work
      ElemName(Some("http://someUri/"),"someNode2") ^^ 
      {
        case p1 ~ p2 ⇒  //......
      }) ^^
      {
        case p1 ⇒  // ....
      })

      //or,I'm not sure which one to choose
      //ElemName(Some("http://someUri/"),"someNode1") |||      // should work also
      //ElemName(Some("http://someUri/"),"someNode2") ^^ 
  }
}

这应该按照我的理解工作.但是,此时它不再编译,因为它说:

constructor cannot be instantiated to expected type;
[error]  found   : SomeTrait.this.~[a,b]
[error]  required: ElemName
[error]           case p1 ~ p2 ⇒ {
[error]                   ^
[error] one error found

我相信我必须用其他东西替换案例p1~p2.

解决方法

问题是|和|||两者都返回一个令牌.特别:

a | b尝试解析a,如果成功则返回,如果失败则尝试解析b
a ||| b尝试解析a和b并使用解析最多字符的结果.我不认为他们中的任何一个都是你想要的.如果它们是,你应该只使用p1而不是p1~p2.我认为你真正想要的是:

phrase(rep(
  ElemName(Some("http://someUri/"),"someNode1").? ~
  ElemName(Some("http://someUri/"),"someNode2").? ^^ 
  {
    case Some(p1) ~ Some(p2) ⇒  //......
    case Some(p1) ~ None => //.....
    case None ~ Some(p2) => //.....
  })

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。