Another code snippet - was trying to parse a XML document in Scala without vars...
Here is the XML:
<apm>
<entry>
<service>GOOGLE</service>
<id>G-ID</id>
<pwd>G-PWD</pwd>
<url>www.google.com</url>
</entry>
<entry>
<service>AMAZON</service>
<id>A-ID</id>
<pwd>A-PWD</pwd>
<url>www.amazon.com</url>
</entry>
</apm>
In the scala code that uses pattern matching and recursion.
package scala.fun
import scala.io.Source
import scala.xml.pull.XMLEventReader
import scala.xml.pull.XMLEvent
import scala.xml.pull.EvElemStart
import scala.xml.pull.EvText
import scala.xml.pull.EvElemEnd
case class Label(val lbl: String)
case class Service(val svr: String)
case class Id(val id: String)
case class Pwd(pwd: String)
case class URL(url: String)
case class Entry(val svr: Service, val id: Id, val pwd: Pwd, val url: URL)
object XmlP {
def parse(xmlf: String): List[Entry] = {
def ip(xmlr: XMLEventReader, xmle: XMLEvent, start: Boolean = true, label: Label = Label(""),
service: Service = Service(""), id: Id = Id(""), pwd: Pwd = Pwd(""), url: URL = URL(""),
entries: List[Entry] = List()): List[Entry] = {
xmle match {
case EvElemStart(pre, lbl, attrs, scope) => ip(xmlr, xmlr.next, true, Label(lbl), service, id, pwd, url, entries)
case EvText(txt) =>
if (start)
label.lbl match {
case "service" => ip(xmlr, xmlr.next, true, label, Service(txt.trim), id, pwd, url, entries)
case "id" => ip(xmlr, xmlr.next, true, label, service, Id(txt.trim), pwd, url, entries)
case "pwd" => ip(xmlr, xmlr.next, true, label, service, id, Pwd(txt.trim), url, entries)
case "url" => ip(xmlr, xmlr.next, true, label, service, id, pwd, URL(txt.trim), entries)
case _ => ip(xmlr, xmlr.next, false, label, service, id, pwd, url, entries)
}
else ip(xmlr, xmlr.next, false, label, service, id, pwd, url, entries)
case EvElemEnd(pre, lbl) => {
val newEntries = if ("entry".equals(lbl)) Entry(service, id, pwd, url) +: entries else entries
if (xmlr.hasNext) ip(xmlr, xmlr.next, false, label, service, id, pwd, url, newEntries) else entries
}
case _ => if (xmlr.hasNext) ip(xmlr, xmlr.next, false, label, service, id, pwd, url, entries) else entries
} // xmle match
} //ip
val xml = new XMLEventReader(Source.fromFile(xmlf))
ip(xml, xml.next)
}
val result = parse("apm.xml")
println(s"result: $result")
def main(args: Array[String]): Unit = {}
}
1 comment:
Good implementation using classic tail recursion!
Post a Comment