9

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?

Abhinav Sarkar
  • 23,534
  • 11
  • 81
  • 97
Daniel Seidewitz
  • 720
  • 8
  • 23

2 Answers2

11

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)
Kevin Wright
  • 49,540
  • 9
  • 105
  • 155
6

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
Guillaume Massé
  • 8,004
  • 8
  • 44
  • 57
  • 1
    This is better than the accepted answer. `"_"` 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. – rumtscho Nov 25 '14 at 06:13
  • dont overestimate this awnser. scala-xml is broken. Use something like https://github.com/lihaoyi/scalatags or https://github.com/chris-twiner/scalesXml – Guillaume Massé Nov 25 '14 at 16:18
  • @GuillaumeMassé Can you please explain what do you mean by "scala-xml is broken". I am beginning to learn "scala-xml". – mukesh210 Dec 17 '18 at 05:16
  • @Mukeshprajapati see http://web.archive.org/web/20150801055953/http://anti-xml.org/ – Guillaume Massé Dec 17 '18 at 15:30