Knows Not Much
Knows Not Much

Reputation: 31526

Using JAXB in Scala to serialize to XML

I wrote this code in Scala to use jaxb to serialize Scala objects to XML (don't want to use Scala native xml capability).

@XmlRootElement(name = "SESSION")
@XmlAccessorType(XmlAccessType.FIELD)
case class Session(
   @XmlAttribute(name="TYPE")
   sessionType: String
) {
   def this() = this("")
}

@XmlRootElement(name = "FOO-BAR")
@XmlAccessorType(XmlAccessType.FIELD)
case class FooBar(
   @XmlElement
   session: Session
) {
   def this() = this(new Session())
}


object JAXBTest extends App {
   val context = JAXBContext.newInstance(classOf[FooBar])
   val fooBar = FooBar(Session("mysession"))
   val stringWriter = new StringWriter()
   val marshaller = context.createMarshaller()
   marshaller.marshal(hHonors, stringWriter)
   println(stringWriter.toString)
}

The produced XML looks like

<FOO-BAR><session><sessionType>mysession</sessionType></session></FOO-BAR>

But the XML I want is

<FOO-BAR><SESSION TYPE="mysession"></SESSION></FOO-BAR>

Upvotes: 2

Views: 1521

Answers (1)

Javathought
Javathought

Reputation: 37

You'll have to use scala type to redefine annotations and use them. See code below and notice the case senstivity used. An other point is for the Session, the name of the XmlElement is on the field in FooBar and not on the class

import io.github.javathought.commons.xml.Macros.{xmlAccessorType, xmlRootElement, xmlAttribute, xmlElement}


import scala.annotation.meta.field

object Macros {
  type xmlRootElement = XmlRootElement @companionClass
  type xmlAccessorType = XmlAccessorType @companionClass
  type xmlElement = XmlElement @field
  type xmlAttribute = XmlAttribute @field

}

@xmlAccessorType(XmlAccessType.FIELD)
case class Session(
                    @xmlAttribute(name="TYPE")
                    sessionType: String
                  ) {
  def this() = this("")
}

@xmlRootElement(name = "FOO-BAR")
@xmlAccessorType(XmlAccessType.FIELD)
case class FooBar(
                   @xmlElement(name = "SESSION")
                   session: Session
                 ) {
  def this() = this(new Session())
}

val hHonors = new FooBar(new Session("Hi"))

val context = JAXBContext.newInstance(classOf[FooBar])
val fooBar = FooBar(Session("mysession"))
val stringWriter = new StringWriter()
val marshaller = context.createMarshaller()
marshaller.marshal(hHonors, stringWriter)
println(stringWriter.toString)

I get the expected string :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><FOO-BAR><SESSION TYPE="Hi"/></FOO-BAR>

Upvotes: 2

Related Questions