I want to select the first child Elem of a Node named "a". What I've got now is:
(xml \ "a")(0).child.collect {case e: Elem => e}
This is quite verbose. I was looking for something like:
xml \ "a" \ "*"
Is this possible in scala?
I want to select the first child Elem of a Node named "a". What I've got now is:
(xml \ "a")(0).child.collect {case e: Elem => e}
This is quite verbose. I was looking for something like:
xml \ "a" \ "*"
Is this possible in scala?
You can't do anything with the existing \
or \\
methods on NodeSeq
.
But you can extend NodeSeq with a new \*
method (note the lack or space character), as per the pimp-your-library pattern:
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)
In the REPL, this then gives me:
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)
This is pretty close to what you are looking for:
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
© 2022 - 2024 — McMap. All rights reserved.
"_"
does exactly what was asked for, without the need to write a new method. Less code to maintain, less non-standard syntax to confuse the next guy looking at your code. – Armallas