We’ve seen in a previous tutorial how to extract primitive types from XML documents. Often, however, these primitive values need to be assembled in more complex types, such as tuples. kantan.xpath provides a simple way of doing so.
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 an (Int, Boolean)
tuple. In order to do that, we need to declare an
implicit NodeDecoder[(Int, Boolean)]
value: this will be automatically picked up by kantan.xpath and
used when we request XML nodes to be interpreted as (Int, Boolean)
values.
The easier way to declare a NodeDecoder
instance for tuples is to use the dedicated tuple
method, which takes
one XPath expression per field to extract:
import kantan.xpath._
import kantan.xpath.implicits._
implicit val elementDecoder: NodeDecoder[(Int, Boolean)] = NodeDecoder.tuple[Int, Boolean](xp"./@id", xp"./@enabled")
Now that we have told kantan.xpath how to decode an XML node to an instance of (Int, Boolean)
, we can simply call
evalXPath
with the right type parameters:
rawData.evalXPath[List[(Int, Boolean)]](xp"//element")
// res1: XPathResult[List[(Int, Boolean)]] = Right(
// value = List((1, true), (2, false), (3, true), (4, false))
// )