2011-01-07 69 views
9

我想選擇名爲「a」的節點的第一個子元素。我現在所得到的是:選擇scala中節點的所有子元素

(xml \ "a")(0).child.collect {case e: Elem => e} 

這是相當冗長。我正在尋找類似的東西:

xml \ "a" \ "*" 

這是可能的斯卡拉?

回答

11

您無法對NodeSeq上的現有\\\方法進行任何操作。 但是你可以用新\*方法(注意缺乏或空格字符)延長NodeSeq,按照皮條客,你的庫模式:

import xml.{NodeSeq, Elem} 

class ChildSelectable(ns: NodeSeq) { 
    def \* = ns flatMap { _ match {          
    case e:Elem => e.child         
    case _ => NodeSeq.Empty         
    } } 
} 

implicit def nodeSeqIsChildSelectable(xml: NodeSeq) = new ChildSelectable(xml) 

在REPL,這則給了我:

scala> val xml = <a><b><c>xxx</c></b></a> 
xml: scala.xml.Elem = <a><b><c>xxx</c></b></a> 

scala> xml \*                    
res7: scala.xml.NodeSeq = NodeSeq(<b><c>xxx</c></b>) 

scala> xml \ "b" \* 
res8: scala.xml.NodeSeq = NodeSeq(<c>xxx</c>) 

scala> xml \ "b" \ "c" \* 
res9: scala.xml.NodeSeq = NodeSeq(xxx) 
6

這是非常接近你正在尋找:

import scala.xml.Elem 

val xml = <a><b><c>HI</c></b></a> 

println(xml) 
println(xml \ "_") 
println(xml \ "b") 
println(xml \ "b" \ "_") 
println(xml \ "b" \ "c") 
println(xml \ "b" \ "c" \ "_") 


<a><b><c>HI</c></b></a> 
<b><c>HI</c></b> 
<b><c>HI</c></b> 
<c>HI</c> 
<c>HI</c> 
// Empty 
+0

釷比接受的答案好。 ``_「`完全符合要求,而不需要編寫新的方法。更少的代碼來維護,更少的非標準語法混淆下一個看你的代碼的人。 – rumtscho 2014-11-25 06:13:20

相關問題