tags:

views:

147

answers:

2

I'm parsing some xml, and given a particular node, I'm trying to figure out which one of these it is:

  • An element with nested elements

    <theElement><nestedElement>foobar</nestedElement></theElement>

  • An element with text/data in it

    <theElement>foobar</theElement>

I've tried checking the length of Node.text, but Node.text returns "foobar" for theElement in both of the above examples.

My code is recursing down through an XML structure, and at each point needs to know if its reached some text/data, or if there are more elements below.

A: 

Maybe this is the solution, tried it out in repl:

scala> val xml1 = <theElement><nestedElement>foobar</nestedElement></theElement>
xml1: scala.xml.Elem = <theElement><nestedElement>foobar</nestedElement></theElement>

scala> val xml2 = <theElement>foobar</theElement>
xml2: scala.xml.Elem = <theElement>foobar</theElement>

scala> xml1.child.first.label
res0: String = nestedElement

scala> xml2.child.first.label
res1: String = #PCDATA

e.g.

if ( node.child.first.label == "#PCDATA" ) {
  // Its got data in it
} else {
  // Its got elements below it
}
Alex Black
+2  A: 
def textChildren(xml: Node) = xml match {
  case Elem(prefix, label, attribs, scope, Text(text)) => println("Only text children: "+text)
  case _ => println("Other kinds of children")
}

scala> textChildren(<a>XML example</a>)
Only text children: XML example

scala> textChildren(<a><nested>XML example</nested></a>)
Other kinds of children

scala> textChildren(<a>Text with <nested>XML</nested> example</a>)
Other kinds of children
Daniel
thx, that works well. Could you also do xml.Child match { case Text(text) => case _ => }?
Alex Black
The method returns a `Seq[Node]`, so you'll probably need to write `case Seq(Text(text)) =>` instead.
Daniel