xml - NodeSeq 匹配失败,但等效的 Elem 匹配成功——为什么?怎么修?

标签 xml scala match

好吧,这让我(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>

那么,两个问题。一:卧槽?为什么会这样?二:我似乎无法找到将 NodeSeq 转换为 Elem 的方法,因此匹配将起作用。执行此操作的正确方法是什么?

最佳答案

NodeSeqNode 的集合,而不是单个节点:

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 少。)

关于xml - NodeSeq 匹配失败,但等效的 Elem 匹配成功——为什么?怎么修?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3480181/

相关文章:

Scala:可以在不带括号的表达式中使用 "foo match { bar }"吗?

python - 匹配并索引所有子字符串,包括重叠的子字符串

awk 3 个连续的空行作为匹配模式

java - XSD - 任何(未知)元素的无限数量,但定义了序列中的最后一个元素

ruby - 如何在 Ruby 中解析 DTD 文件

xml - 更改XML属性的值会删除其他属性

scala - 我该如何管理案例类的构造函数?

scala - Play 2.4 禁用基于请求路径或方法设置的某些过滤器

android - ImageView 的自定义边框

regex - 匹配除列出的每个单词