Scala for Java developers — working with xml

We all know and love java. Java is a stable language with a huge community, endless amount of libraries, with more than million Q&A in Stack Overflow and hundreds of java experts around the globe. So it probably makes you wonder why should I even learn scala, what is it good for? 
we as programmers don’t have spare time on our hands and scala is considered to be HARD with a steep learning curve. Yet, you can benefit from learning scala especially if you’re a big data developer. From my experience, working with Apache Spark is much easier when coding in scala. Most of Apache Spark code base is actually written in scala, and every experienced developer will find himself checking the implementation of certain methods that Apache Spark provides. So you should at least understand it and the best way to do it is by practicing it! and what is a better way to practice then writing it yourself ?!

Should we start?

There are many ways to process XML files in java. One of them is using DOM parser library. DOM is considered to be complex and this is where scala makes our life easier.

Scala standard libraries provide xml functionalities:

import scala.xml._

In the next example we will iterate over an xml tree using scala Elem object:

val sweetNode: Elem =
<sweet>
<dough type="thin" size="14"/>
<topping>choclate</topping>
<topping>blueberries</topping>
</sweet>
for (topping <- sweetNode \ "topping") {
handleSweetNode(topping)
}

for (dough <- sweetNode \ "dough") {
handleSweetNode(dough)
}

in the code above we see how we can easily create an Elem which is part of our XML and iterate over it using the projection ( \ ) function, here is part of the documentation of the projection function:

 is a Projection function, which returns  elements of `this` sequence based
* on the string
`that`. Use:
* -
`this \ "foo"` to get a list of all elements that are labelled with `"foo"`;
* -
`\ "_"` to get a list of all elements (wildcard);
* -
`ns \ "@foo"` to get the unprefixed attribute `"foo"`;
* -
`ns \ "@{uri}foo"` to get the prefixed attribute `"p

In the handling process we use the pattern matching of scala with regex which help us iterate over the xml.

in the first case we are looking for Elem with inside text, when handling this case, value will be the our pointer to the object:

case <topping>{value}</topping> => println(s"Got a topping: $value")

it’s important to notice that scala is sensitive about the content of the tags and pattern matching, meaning that tag with text inside will be considered different then tag without any text inside:

<topping>{value}</topping> is not equal to <topping></topping>

In the next case we would like to handle the dough. The dough is a complex tag which has size and type. The @ operator help us match the dough case which means that parameter dough is now assigned to the data inside <dough /> tag which translate into in Elem as well.

case dough @ <dough />

The function of handling a sweet tooth(Node) :

def handleSweetNode(sweetNode: Node): Unit = {
sweetNode match {
case <topping>{value}</topping> => println(s"Got a topping: $value")
case dough @ <dough/> =>
val doughSize = dough \ "@size"
val doughType = dough \ "@type"
println(s"doughSize: $doughSize, doughType: $doughType")
case _ => println("no sweets for you!")
}
}

And here is the complete code:

class XmlFunctionality {

def sweetsTime(): Unit = {
val sweetNode: Elem =
<sweet>
<dough type="thin" size="14"/>
<topping>choclate</topping>
<topping>blueberries</topping>
</sweet>

println("------ matching expression -------")

for (topping <- sweetNode \ "topping") {
handleSweetNode(topping)
}

for (dough <- sweetNode \ "dough") {
handleSweetNode(dough)
}
}

def handleSweetNode(sweetNode: Node): Unit = {
sweetNode match {
case <topping>{value}</topping> => println(s"Got a topping: $value")
case dough @ <dough/> =>
val doughSize = dough \ "@size"
val doughType = dough \ "@type"
println(s"doughSize: $doughSize, doughType: $doughType")
case _ => println("no sweets for you!")
}
}
}



object XmlFunctionality {
def main(args: Array[String]) {
val lesson = new XmlFunctionality()
lesson.sweetsTime()
}
}

Output is:

— — — matching expression — — — -
Got a topping: choclate
Got a topping: blueberries
doughSize: 14, doughType: thin

For more information regarding the xml objects stracture and abilities visit:

http://www.codecommit.com/blog/scala/working-with-scalas-xml-support