How to generate case class with annotation using ScalaXB

235 Views Asked by At

I am using the ScalaXB plugin to convert XSD files to Scala case classes and it is working fine but is there any way to add javax.xml.bind.annotation with it?

The reason I need is to marshal/unmarshal XML to generated classes and I am using JAXB but it is giving me the error that generated classes do not have a no-arg default constructor.

If not is there any other library to convert XSD files to Java files in sbt? I found sbt-xjc but I think it is not in active development.

File Generated from scalaxb

// Generated by <a href="http://scalaxb.org/">scalaxb</a>.
package generated

case class EmployeeType(FirstName: String,
  LastName: String,
  Age: Int,
  Email: String)

For parsing I am using Jaxb

  import javax.xml.bind._
  import java.io.StringReader

  def unmarshalXML[T](xmlString: String)(implicit tag: reflect.ClassTag[T]): Option[T] = {
    try {
      val context = JAXBContext.newInstance(tag.runtimeClass)
      val unmarshaller = context.createUnmarshaller()
      val instance = unmarshaller.unmarshal(new StringReader(xmlString)).asInstanceOf[T]
      Some(instance)
    } catch {
      case ex: Exception =>
        ex.printStackTrace()
        None
    }
  }

Stack Trace

Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
generated.EmployeeType does not have a no-arg default constructor.
    this problem is related to the following location:
        at generated.EmployeeType
1

There are 1 best solutions below

1
On

Figured out the solution.

Highlight: Don't use JAXB for marshaling and unmarshalling. Instead, use scalaxb only.

When we generate file using scalaxb it generates 2 extra files named: scalaxb .scala under package scalaxb and xmlprotocol.scala unded generated package. scalaxb.scala contains the required method to perform necessary operation on XML. For example,

We can use fromXML and toXML method for marshaling and unmarshalling.

import scalaxb
import generated._
import scala.xml.XML

val xmlElem = XML.loadString(xmlString)
val employeeType = scalaxb.fromXML[EmployeeType](xmlElem)
val backToXMLString = scalaxb.toXML[EmployeeType(employeeType, "EMPLOYEETYPE", generated.defaultScope)