We’ve seen in a previous tutorial how to extract tuples from XML documents. The next step up from tuples is case classes, which work in a very similar fashion.
In order to show how that works, we’ll first need some sample XML data, which we’ll get from this project’s resources:
val rawData: java.net.URL = getClass.getResource("/simple.xml")
This is what we’re working with:
scala.io.Source.fromURL(rawData).mkString
// res0: String = """<root>
// <element id="1" enabled="true"/>
// <element id="2" enabled="false"/>
// <element id="3" enabled="true"/>
// <element id="4" enabled="false"/>
// </root>"""
We’ll be trying to turn each element
node into values of the following type:
final case class El(id: Int, enabled: Boolean)
In the same way that we had to declare a NodeCoder[(Int, Boolean)]
to decode tuples, we’ll need a
NodeDecoder[El]
for this case class, which we can easily create through the decoder
method:
import kantan.xpath._
import kantan.xpath.implicits._
// There is no need to specify type parameters here, the Scala compiler works them out from El.apply.
implicit val elDecoder: NodeDecoder[El] = NodeDecoder.decoder(xp"./@id", xp"./@enabled")(El.apply)
Now that we have told kantan.xpath how to decode an XML node to an instance of El
, we can simply call
evalXPath
with the right type parameters:
rawData.evalXPath[List[El]](xp"//element")
// res1: XPathResult[List[El]] = Right(
// value = List(
// El(id = 1, enabled = true),
// El(id = 2, enabled = false),
// El(id = 3, enabled = true),
// El(id = 4, enabled = false)
// )
// )