即使scalaxb并未提及使用scalaxb的生成模式对JSON进行反序列化/序列化的方法,但是有没有办法使用Play JSON构建自己的格式化程序?
我面临的问题是反序列化生成的名为DataRecord
的类
trait DataRecord[+A] {
val namespace: Option[String]
val key: Option[String]
val value: A
def as[B] = value.asInstanceOf[B]
override def toString: String = {
"DataRecord(" +
((namespace, key, value) match {
case (None, Some(k), _) => k + "," + value.toString
case (Some(n), Some(k), _) => "{" + n + "}" + k + "," + value.toString
case _ => value.toString
}) + ")"
}
}
object DataRecord extends XMLStandardTypes {
private case class DataWriter[+A](
namespace: Option[String],
key: Option[String],
xstypeNamespace: Option[String],
xstypeName: Option[String],
value: A,
writer: CanWriteXML[_]) extends DataRecord[A] {
override def equals(o: Any): Boolean =
o match {
case that: DataWriter[_] =>
namespace == that.namespace &&
key == that.key &&
value == that.value
case _ => false
}
override def hashCode: Int = {
var result = 17
result = result + 31 * namespace.hashCode
result = result + 31 * key.hashCode
result = result + 31 * value.hashCode
result
}
}
import Helper._
// this is for nil element.
def apply(namespace: Option[String], key: Option[String], value: None.type): DataRecord[Option[Nothing]] =
DataWriter(namespace, key, None, None, value, __NoneXMLWriter)
// this is for choice option: DataRecord(x.namespace, Some(x.name), fromXML[Address](x))
def apply[A:CanWriteXML](namespace: Option[String], key: Option[String], value: A): DataRecord[A] =
DataWriter(namespace, key, None, None, value, implicitly[CanWriteXML[A]])
def apply[A:CanWriteXML](node: Node, value: A): DataRecord[A] = node match {
case elem: Elem =>
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
DataRecord(ns, key, value)
case _ => DataRecord(value)
}
// this is for long attributes
def apply[A:CanWriteXML](x: Node, parent: Node, value: A): DataRecord[A] = x match {
case _ => DataRecord(value)
}
def apply[A:CanWriteXML](value: A): DataRecord[A] =
apply(None, None, value)
def apply[A:CanWriteXML](namespace: Option[String], key: Option[String],
xstypeNamespace: Option[String], xstypeName: Option[String], value: A): DataRecord[A] =
DataWriter(namespace, key, xstypeNamespace, xstypeName, value, implicitly[CanWriteXML[A]])
// this is for any.
def apply(elemName: ElemName)(implicit handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = fromAny(elemName.node, handleNonDefault)
def fromAny(seq: NodeSeq, handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = {
seq match {
case elem: Elem => fromAny(elem, handleNonDefault)
case _ => DataRecord(None, None, None, None, seq.text)
}
}
def fromAny(elem: Elem, handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = {
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
val XS = Some(XML_SCHEMA_URI)
instanceType(elem) match {
case (XS, xstype) =>
xstype match {
case Some("int") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("byte") => DataRecord(ns, key, XS, xstype, fromXML[Byte](elem, Nil))
case Some("short") => DataRecord(ns, key, XS, xstype, fromXML[Short](elem, Nil))
case Some("long") => DataRecord(ns, key, XS, xstype, fromXML[Long](elem, Nil))
case Some("float") => DataRecord(ns, key, XS, xstype, fromXML[Float](elem, Nil))
case Some("double") => DataRecord(ns, key, XS, xstype, fromXML[Double](elem, Nil))
case Some("integer") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("nonPositiveInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("negativeInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("nonNegativeInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("positiveInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("unsignedLong") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("unsignedInt") => DataRecord(ns, key, XS, xstype, fromXML[Long](elem, Nil))
case Some("unsignedShort") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("unsignedByte") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("decimal") => DataRecord(ns, key, XS, xstype, fromXML[BigDecimal](elem, Nil))
case Some("boolean") => DataRecord(ns, key, XS, xstype, fromXML[Boolean](elem, Nil))
case Some("string") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("normalizedString") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("token") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("language") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("Name") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NCName") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NMTOKEN") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NMTOKENS") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("ID") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("IDREF") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("IDREFS") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("ENTITY") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("ENTITIES") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("hexBinary") => DataRecord(ns, key, XS, xstype, fromXML[HexBinary](elem, Nil))
case Some("base64Binary") => DataRecord(ns, key, XS, xstype, fromXML[Base64Binary](elem, Nil))
case Some("anyURI") => DataRecord(ns, key, XS, xstype, fromXML[java.net.URI](elem, Nil))
case Some("QName") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.namespace.QName](elem, Nil))
case Some("NOTATION") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.namespace.QName](elem, Nil))
case Some("duration") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.datatype.Duration](elem, Nil))
case Some("dateTime") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("time") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gYearMonth") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gYear") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gMonthDay") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gDay") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gMonth") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case _ => DataRecord(ns, key, XS, xstype, elem)
}
case _ => handleNonDefault(elem).getOrElse {
val (xsns, xstype) = instanceType(elem)
DataRecord(ns, key, xsns, xstype, elem)
}
}
}
// this is for any.
def fromNillableAny(seq: NodeSeq): DataRecord[Option[Any]] = {
seq match {
case elem: Elem => fromNillableAny(elem)
case _ => DataRecord(None, None, None, None, Some(seq.text))
}
}
// this is for any.
def fromNillableAny(elem: Elem): DataRecord[Option[Any]] = {
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
val XS = Some(XML_SCHEMA_URI)
if (isNil(elem)) DataRecord(ns, key, None)
else instanceType(elem) match {
case (XS, xstype) =>
xstype match {
case Some("int") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("byte") => DataRecord(ns, key, XS, xstype, Some(fromXML[Byte](elem, Nil)))
case Some("short") => DataRecord(ns, key, XS, xstype, Some(fromXML[Short](elem, Nil)))
case Some("long") => DataRecord(ns, key, XS, xstype, Some(fromXML[Long](elem, Nil)))
case Some("float") => DataRecord(ns, key, XS, xstype, Some(fromXML[Float](elem, Nil)))
case Some("double") => DataRecord(ns, key, XS, xstype, Some(fromXML[Double](elem, Nil)))
case Some("integer") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("nonPositiveInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("negativeInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("nonNegativeInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("positiveInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("unsignedLong") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("unsignedInt") => DataRecord(ns, key, XS, xstype, Some(fromXML[Long](elem, Nil)))
case Some("unsignedShort") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("unsignedByte") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("decimal") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigDecimal](elem, Nil)))
case Some("boolean") => DataRecord(ns, key, XS, xstype, Some(fromXML[Boolean](elem, Nil)))
case Some("string") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("normalizedString") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("token") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("language") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("Name") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NCName") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NMTOKEN") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NMTOKENS") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("ID") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("IDREF") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("IDREFS") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("ENTITY") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("ENTITIES") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("hexBinary") => DataRecord(ns, key, XS, xstype, Some(fromXML[HexBinary](elem, Nil)))
case Some("base64Binary") => DataRecord(ns, key, XS, xstype, Some(fromXML[Base64Binary](elem, Nil)))
case Some("anyURI") => DataRecord(ns, key, XS, xstype, Some(fromXML[java.net.URI](elem, Nil)))
case Some("QName") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.namespace.QName](elem, Nil)))
case Some("NOTATION") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.namespace.QName](elem, Nil)))
case Some("duration") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.datatype.Duration](elem, Nil)))
case Some("dateTime") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("time") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gYearMonth") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gYear") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gMonthDay") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gDay") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gMonth") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case _ => DataRecord(ns, key, XS, xstype, Some(elem))
}
case _ =>
val (xsns, xstype) = instanceType(elem)
DataRecord(ns, key, xsns, xstype, Some(elem))
}
}
def unapply[A](record: DataRecord[A]): Option[(Option[String], Option[String], A)] =
Some((record.namespace, record.key, record.value))
def toXML[A](obj: DataRecord[A], namespace: Option[String], elementLabel: Option[String],
scope: scala.xml.NamespaceBinding, typeAttribute: Boolean): scala.xml.NodeSeq = obj match {
case w: DataWriter[_] =>
obj.value match {
case seq: NodeSeq =>
w.writer.asInstanceOf[CanWriteXML[A]].writes(obj.value, namespace, elementLabel, scope, typeAttribute)
case _ =>
w.writer.asInstanceOf[CanWriteXML[A]].writes(obj.value, namespace, elementLabel, scope, false) match {
case elem: Elem if (w.xstypeName.isDefined && scope.getPrefix(XSI_URL) != null) =>
elem % scala.xml.Attribute(scope.getPrefix(Helper.XSI_URL), "type",
Helper.prefixedName(w.xstypeNamespace, w.xstypeName.get, scope), scala.xml.Null)
case x => x
}
}
case _ => sys.error("unknown DataRecord.")
}
}
据我了解,该类对于反序列化为JSON并不重要。
但是我有生成的类继续使用myFieldOnCaseClass: DataRecord[MyTypeY]
甚至是myCaseClassNameOption2: Option[DataRecord[Any]] = None
。
有没有一种方法可以为DataRecord
生成play json的格式,从而使monad被“忽略”?
documentation是指同时为实现类和特征创建格式化程序,但是DataRecord
的实现类DataWriter
是一个私人案例类,{ {1}}没有密封,这是否意味着我需要更改生成的代码?
如果无法自动生成格式,是否有人知道scalaxb如何创建DataRecord
的实例?