好吧,这对我(Scala的新秀)以及我的同事(在Scala更先进)感到困惑。 Scala 2.8.0。以下是该问题的演示:
// I've got a var with some XML in it
scala> qq2
res9: scala.xml.Elem = <a><a1>A1</a1><bs><b>B1</b><c>C1</c><d>D1</d></bs></a>
// I can extract sub-elements
scala> (qq2 \ "bs")
res10: scala.xml.NodeSeq = NodeSeq(<bs><b>B1</b><c>C1</c><d>D1</d></bs>)
// but if I try to match against this NodeSeq, it fails to match
scala> (qq2 \ "bs") match {case <bs>{x @ _*}</bs> =>
for (xx <- x) println("matched " + xx) }
scala.MatchError: <bs><b>B1</b><c>C1</c><d>D1</d></bs>
at .<init>(<console>:7)
at ...
// but if I just type in the XML directly, it works as expected
scala> <bs><b>B1</b><c>C1</c><d>D1</d></bs> match {
case <bs>{x @ _*}</bs> => for (xx <- x) println("matched " + xx) }
matched <b>B1</b>
matched <c>C1</c>
matched <d>D1</d>
// presumably because it's of type Elem, not NodeSeq
scala> <bs><b>B1</b><c>C1</c><d>D1</d></bs>
res13: scala.xml.Elem = <bs><b>B1</b><c>C1</c><d>D1</d></bs>
所以,两个问题。一:wtf?为什么会这样?二:我似乎无法找到将NodeSeq转换为Elem的方法,因此匹配将起作用。什么是正确的方法?
答案 0 :(得分:6)
NodeSeq
是Node
的集合,而不是单个节点:
scala> (<a><b>1</b><b>2</b></a>) \ "b"
res0: scala.xml.NodeSeq = NodeSeq(<b>1</b>, <b>2</b>)
所以你必须匹配节点:
scala> ((<a><b>1</b><b>2</b></a>) \ "b").map(_ match {
| case <b>{x}</b> => true
| case _ => false
| })
res24: scala.collection.immutable.Seq[Boolean] = List(true, true)
(节点往往是Elems,所以这很好。我不知道分离背后的原因;我猜一些节点与它们的关联性比Elem少。)
答案 1 :(得分:4)
方法\
返回一系列有效答案,而不是单个元素。这里:
scala> val qq2 = <a><a1>A1</a1><bs><b>B1</b><c>C1</c><d>D1</d></bs></a>
qq2: scala.xml.Elem = <a><a1>A1</a1><bs><b>B1</b><c>C1</c><d>D1</d></bs></a>
scala> (qq2 \ "bs") match {case Seq(<bs>{x @ _*}</bs>) => //<-I added a Seq()
| for (xx <- x) println("matched " + xx) }
matched <b>B1</b>
matched <c>C1</c>
matched <d>D1</d>