2

考虑以下 XML 节点:

 <Interval>
   <P v="1"/>
   <Q v="0.0"/>
  </Interval>

在 Scala 中模式匹配顶级元素的正确方法是什么?我希望以下内容可以工作,但事实并非如此:

def visit(node:Node):String = {
    node match {
        case p @ <P/> => (p \ "@v") text
        case q @ <Q/> => (q \ "@v") text
        case <Interval> @ children:_* </Interval> => "parent"
    }
}
4

2 回答 2

2

当您在 Scala 中创建 XML 文字时,您分配给它的变量顶级元素。

val node: scala.xml.Elem =
  <Interval>
   <P v="1"/>
   <Q v="0.0"/>
  </Interval> 

要匹配顶级元素 hereInterval或任何Interval具有子元素的元素,例如您的示例,您可以使用花括号来匹配子元素。

node match {
  case <Interval>{ children @_* }</Interval> => children.collect {
    case p @ <P/> => p \@ "v"
    case q @ <Q/> => q \@ "v"
  }
}

结果是:

Seq("1", "0.0")

如果您不熟悉collect,它允许您提供部分函数(读作“模式匹配”)并忽略否则会因匹配错误而失败的情况。

于 2019-04-08T23:07:03.137 回答
0

scala中的这个表达式:

<Interval>
 <P v="1"/>
 <Q v="0.0"/>
</Interval>

肯定会scala.xml.Node在 scala 中返回 a 但首先是 a scala.xml.Elem。您可以像这样对其进行模式匹配:

import scala.xml.Elem

def visit(elem: Elem) = {
    elem match {
        case e@Elem(_, "Interval",_, _, _*) => "identified!"
    }
}

或者您也可以在 the 上进行模式匹配child,因为您对类型Elem 的对象 n 进行模式匹配就像Elem(n.prefix, n.label, n.attributes, n.scope, n.child)并且这里child的元素(它是 a Seq)与模式的每个剩余元素匹配:

def visit(elem: Elem) = {
    elem match {
        case Elem(_, "Interval",_, _, emptyElem, nodeIWant@(<P/>), _*) =>
        (nodeIWant \ "@v").text
    }
}

例如返回1这里。

希望能帮助到你。

于 2019-04-08T14:19:19.890 回答