pdvrieze / xmlutil

XML Serialization library for Kotlin
https://pdvrieze.github.io/xmlutil/
Apache License 2.0
377 stars 30 forks source link

Value class causes wrong order during serialization #195

Open hfhbd opened 7 months ago

hfhbd commented 7 months ago

Hey, I expect the order of the encoded elements would be the same as the order of the declaration:

@Serializable
@XmlSerialName("Foo")
data class Foo(
  @XmlElement
  @XmlSerialName("ServiceName")
  val serviceName: String? = null,

  @XmlElement
  @XmlSerialName("SendingSystem")
  val sendingSystem: Code? = null,
) {
  @JvmInline
  @Serializable
  @XmlSerialName("Code")
  value class Code(
    val `value`: String,
  )
}
assertEquals(
  expected = "<Foo><ServiceName>a</ServiceName><SendingSystem>b</SendingSystem></Foo>",
  actual = XML.encodeToString(foo) // <Foo><SendingSystem>b</SendingSystem><ServiceName>a</ServiceName></Foo>
)

Kotlin 1.9.22 Kotlinx serialization core: 1.6.2 XmlUtil: 0.86.3

There is a workaround though using a regular data class:

@Serializable
@XmlSerialName("Foo")
data class Foo2(
  @XmlElement
  @XmlSerialName("ServiceName")
  val serviceName: String? = null,

  @XmlElement
  @XmlSerialName("SendingSystem")
  val sendingSystem: Code? = null,
) {
  @Serializable
  @XmlSerialName("Code")
  data class Code(
    @XmlValue
    val `value`: String,
  )
}
pdvrieze commented 7 months ago

I had a look. This was indeed a problem with handling reordering in the "correct way" - reordering must be delayed for the actual inline value (a special case), but then the actual child wasn't reordered properly.

pdvrieze commented 7 months ago

The fix should be available in the snapshots.

hfhbd commented 7 months ago

Thanks, will try it out next days.