Consider the following XML node:
<Interval>
<P v="1"/>
<Q v="0.0"/>
</Interval>
What is the correct way to pattern match the top level element in Scala? I would expect the following to work but it does not:
def visit(node:Node):String = {
node match {
case p @ <P/> => (p \ "@v") text
case q @ <Q/> => (q \ "@v") text
case <Interval> @ children:_* </Interval> => "parent"
}
}
答案 0 :(得分:2)
在Scala中创建XML文字时,分配给它的变量 是顶级元素。
val node: scala.xml.Elem =
<Interval>
<P v="1"/>
<Q v="0.0"/>
</Interval>
要匹配顶级元素(例如Interval
或Interval
中具有子元素的任何元素,例如您的示例),可以使用大括号来匹配子元素。
node match {
case <Interval>{ children @_* }</Interval> => children.collect {
case p @ <P/> => p \@ "v"
case q @ <Q/> => q \@ "v"
}
}
结果是:
Seq("1", "0.0")
如果您不熟悉collect
,则可以使用它提供部分函数(读为“模式匹配”),并忽略否则会由于匹配错误而失败的情况。
答案 1 :(得分:0)
scala中的此表达式:
<Interval>
<P v="1"/>
<Q v="0.0"/>
</Interval>
肯定会在scala中返回scala.xml.Node
,但首先返回scala.xml.Elem
。您可以像这样对它进行图案匹配:
import scala.xml.Elem
def visit(elem: Elem) = {
elem match {
case e@Elem(_, "Interval",_, _, _*) => "identified!"
}
}
或者您也可以在child
上进行模式匹配,因为您在类型Elem
的对象n上进行模式匹配就像Elem(n.prefix, n.label, n.attributes, n.scope, n.child)
以及此处的child
元素(这是一个Seq
)与模式的其余每个元素匹配:
def visit(elem: Elem) = {
elem match {
case Elem(_, "Interval",_, _, emptyElem, nodeIWant@(<P/>), _*) =>
(nodeIWant \ "@v").text
}
}
例如在此处返回1
。
希望有帮助。