Skip to content

Instantly share code, notes, and snippets.

View novakov-alexey-zz's full-sized avatar
🎸
FP user

Alexey Novakov novakov-alexey-zz

🎸
FP user
View GitHub Profile

From scala.xml.pull to javax.xml.stream.events

Want to process XML that's too large to fit in memory?

The Scala standard library used to offer scala.xml.pull for this. It became part of the scala-xml library when scala-xml became separate. But then scala.xml.pull got deprecated (in scala.xml 1.1.1) and finally removed entirely (in scala-xml 2.0.0-M1). The recommended replacement is javax.xml.stream.events.

I had some old code that used scala.xml.pull to digest my iTunes Music Library.xml and print various statistics. Recently I converted it to Scala 3, so I decided to get off the deprecated API at the same time.

So, here is the before-and-after. Perhaps this will help other users of scala.xml.pull who want to convert.

observations.foldLeft(
List[Observation]() -> WindowStats(0, Int.MaxValue, Int.MinValue, 0)
) {
case ((series, stats), ob) =>
@tailrec
def calcStats(
st: WindowStats,
obs: List[Observation]): (WindowStats, List[Observation]) = {
case class Observation(time: Long, value: Double)
// contains 4 additional columns we need to calculate for each event
case class WindowStats(sum: Double, min: Double, max: Double, count: Int)
/**
*
* @param edgeTo a sequence which represents the last edge
* on the shortest path from 'sourceV' to vertex i.
* None means there is no path to vertex i
* @param distTo a sequence of distances from source vertex to a specific i vertex
*/
class ShortestPathCalc(edgeTo: Seq[Option[DirectedEdge]], distTo: Seq[Double]) {
/**
*
object ShortestPath {
/**
* Function tries to find a shortest path from source vertex
* to all other vertices in the graph
*
* @param g EdgeWeightedDigraph to find a shortest path
* @param sourceV source vertex to find a shortest path from
* @return return either error as string when input parameters
* are invalid or return shortest path result
*/
/**
* Algorithm is based on Java version implemented
* by Princeton University https://algs4.cs.princeton.edu/44sp/
*/
final case class DirectedEdge(from: Int, to: Int, weight: Double)
final case class EdgeWeightedDigraph(adj: Map[Int, List[DirectedEdge]] = Map.empty)
object EdgeWeightedDigraphOps {
lazy val root = (project in file(".")).settings(
inThisBuild(List(organization := "org.alexeyn", scalaVersion := "2.12.7")),
name := "akka-crud-service",
libraryDependencies ++= Seq(
...
),
dockerBaseImage := "openjdk:8-jre-alpine"
).enablePlugins(JavaAppPackaging, AshScriptPlugin)
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.{DefaultJsonProtocol, DeserializationException, JsString, JsValue, JsonFormat, RootJsonFormat}
trait JsonCodes extends SprayJsonSupport with DefaultJsonProtocol {
implicit val trip: RootJsonFormat[Trip] = jsonFormat7(Trip)
implicit val trips: RootJsonFormat[Trips] = jsonFormat1(Trips)
implicit val commandResult: RootJsonFormat[CommandResult] = jsonFormat1(CommandResult)
object Main extends App with StrictLogging {
implicit val system: ActorSystem = ActorSystem("crud-service")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContext = system.dispatcher
val (server, cfg) = AppConfig.load.fold(e => sys.error(e.toString), identity)
val mod = new Module(true, cfg)
val serverBinding = Http().bindAndHandle(mod.routes, server.host, server.port)
serverBinding.onComplete {
class Module(createSchema: Boolean = true, cfg: Config = ConfigFactory.load())(
implicit system: ActorSystem,
executionContext: ExecutionContext
) extends StrictLogging {
val db = Database.forConfig("storage", cfg)
val dao = new TripDao(db)
val service = new TripService(dao)
val routes: Route = concat(QueryRoutes.routes(service), CommandRoutes.routes(service))