代码之家  ›  专栏  ›  技术社区  ›  Harlan

NodeSeq匹配失败,但等效元素匹配成功-为什么?如何修复?

  •  3
  • Harlan  · 技术社区  · 14 年前

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

    所以,有两个问题。一:世贸论坛?为什么是这样?第二:我似乎找不到一种方法把NodeSeq转换成Elem,这样匹配就可以了。正确的方法是什么?

    2 回复  |  直到 14 年前
        1
  •  4
  •   Ken Bloom    14 年前

    方法 \ 返回有效答案的序列,而不是单个元素。在这里:

    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>
    
        2
  •  6
  •   Rex Kerr    14 年前

    A NodeSeq 是一个 Node s、 没有一个节点:

    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)