我正在尝试使用Scala中的Xstream将类型为Option[T]
的对象转换为XML。我有一个这样的案例类:
case class MyModel(promos: Option[Promos])
如果选项为Some(Promo)
,我希望它呈现
<MyModel>
<Promos>
<promoField1>value</promoField1>
<promoField2>value</promoField2>
</Promos>
</MyModel>
如果选项为None
,我希望它呈现
<MyModel>
<Promos/>
</MyModel>
到目前为止,在我的解决方案中,我已经注册了一个转换器:
xstream.registerConverter(new OptionConverter(xstream.getMapper))
然后我有一个如下所示的自定义转换器:
private [xml] class OptionConverter(_mapper: Mapper) extends AbstractCollectionConverter(_mapper: Mapper) {
override def marshal(source: scala.Any, writer: HierarchicalStreamWriter, context: MarshallingContext): Unit = {
val opt = source.asInstanceOf[Option[_]]
for (value <- opt) {
writeItem(value, context, writer)
}
}
override def unmarshal(reader: HierarchicalStreamReader, context: UnmarshallingContext): AnyRef = {
throw new UnsupportedOperationException
}
override def canConvert(clazz: Class[_]): Boolean = {
clazz.isAssignableFrom(classOf[Some[_]]) || clazz.isAssignableFrom(None.getClass)
}
}
None
工作正常,但Some(promo)
输出如下:
<Promos>
<com.mymodel.Promos>
<promoField1>value</promoField1>
<promoField2>value</promoField2>
</com.mymodel.Promos>
</Promos>
问题是,正在为我的Option/Some
字段输出Promos,然后输出“com.mymodel.Promos”作为Some
内的嵌套值。有没有办法压扁Some(value)
?
答案 0 :(得分:0)
我设法使Option
转换器将对象编组为XML。 (我不需要阅读部分,所以我把它留下了未实现的内容)
import com.thoughtworks.xstream.converters.{MarshallingContext, UnmarshallingContext}
import com.thoughtworks.xstream.io.{HierarchicalStreamReader, HierarchicalStreamWriter}
private [xml] sealed class OptionConverter extends com.thoughtworks.xstream.converters.Converter {
override def marshal(source: scala.Any, writer: HierarchicalStreamWriter, context: MarshallingContext): Unit = {
val opt = source.asInstanceOf[Option[_]]
for (value <- opt) {
context.convertAnother(opt.get)
}
}
override def unmarshal(reader: HierarchicalStreamReader, context: UnmarshallingContext): AnyRef = {
throw new UnsupportedOperationException
}
override def canConvert(clazz: Class[_]): Boolean = {
clazz.isAssignableFrom(classOf[Some[_]]) || clazz.isAssignableFrom(None.getClass)
}
}