XDoc is a utility wrapper over scala.xml.Elem. It’s simplifies xml processing. Following needs to be considered while using this utility:

1) It does not support namespaces. That can easily incorporated - But our use case did not have any namespaces.
2) It does not consider text within an element to be a child element of the container as opposed to normal convention - But text can set and retrieved from an element.

Following REPL session shows how to use it.

Shows how to create an instance XDoc:

scala> var d = XDoc(“animals”) addChild “tiger” addChild “lion” addAttr(“test”, “attrValue”)
d: XDoc = 

   

Querying child count:

scala> d.childCount
res13: Int = 2

Setting text :

scala> d = d.setText(“Sample text”)
d: XDoc =   Sample text    

Shows that text is not considered as a child:

scala> d.childCount
res14: Int = 2

scala> d = d addChild(XDoc(“zebra”).addAttr(“hasStripes”, “true”))
d: XDoc =   Sample text      

scala> d.childCount
res15: Int = 3

scala> d = d.addAttr(“test2”, “Value”)
d: XDoc =   Sample text      

Querying attributes. Attributes are an instance of the case class :

case class XAttr(name: String, value: String)

scala> val atrs = d.attrs
atrs: List[XAttr] = List(XAttr(test,attrValue), XAttr(test2,Value))

scala> d.hasAttrs
res16: Boolean = true

scala> d.attr(“test2”)
res17: Option[XAttr] = Some(XAttr(test2,Value))

scala> d.attr(“testxx”)
res18: Option[XAttr] = None

Querying childrens :

scala> d.childrenByName(“tiger”)
res20: List[XDoc] = List()

scala> d = d addChild((XDoc(“tiger”).addAttr(“male”, “true”)) addChild “females”)
d: XDoc =   Sample text              

scala> d.childrenByName(“tiger”)
res21: List[XDoc] = 
List(,   )

Filtering children based on a predicate:

scala> d = d filter(_.name !=”zebra”)
d: XDoc =            

Checking existence of children based on predicate:

scala> d exists(_.isChildLess == false)
res22: Boolean = true

scala> val tigerWithFemales = d filter (_.isChildLess == false)
tigerWithFemales: XDoc = 

       

Mapping over child elements and transforming them:

scala> d = d map (_.addAttr(“wild”,”true”))
d: XDoc =            

Finding based on a predicate condition on children:

scala> val withFemale = d find(_.isChildLess == false)
withFemale: Option[XDoc] = 
Some(   )

Checking if some conditions holds for all children:

scala> d forall(_.attr(“wild”) match {
     |   case None => false
     |   case Some(x) => true
     |   })
res23: Boolean = true

Finally, we can partition the elements based on some criteria.

scala> val (d1, d2) = d partition (_.isChildLess)
d1: XDoc = 

   

d2: XDoc = 

       

As can be seen XDoc can be pretty handy for dealing with xmls without namespaces. It is an utility class of a bigger project - And can be improved upon. In the mean while the source can be found at:

https://github.com/ratulb/scala-xml-wrapper

Originally published on https://rbsomeg.blogspot.com