Scala 中 XStream 的选项转换器
Option converter for XStream in Scala
我正在尝试在 Scala 中使用 Xstream 将类型 Option[T]
的对象转换为 XML。我有一个案例 class 是这样的:
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,然后为 Some
中的嵌套值输出 "com.mymodel.Promos"。 Some(value)
?
有没有办法展平
我设法使 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)
}
}
我正在尝试在 Scala 中使用 Xstream 将类型 Option[T]
的对象转换为 XML。我有一个案例 class 是这样的:
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,然后为 Some
中的嵌套值输出 "com.mymodel.Promos"。 Some(value)
?
我设法使 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)
}
}