xml icon indicating copy to clipboard operation
xml copied to clipboard

Preserve order while deserializing

Open futile opened this issue 9 years ago • 4 comments

Assume the following xml:

<parent>
  <objA/>
  <objB/>
  <objA/>
</parent>

How can I deserialize this in a fashion that preserves the order 'objA' 'objB' 'objA'?

Deserializing into a Vec<ObjA> and a Vec<ObjB> would not preserve the information that the single ObjB was deserialized between the other two.

I guess in this case an enum like enum Obj { ObjA, ObjB}, and then a Vec<Obj> would make sense, but from what I saw in the tests this only works when the xml looks like <obj xsi:type="ObjA"> etc.

Is there a good way to do this (without deserializing the whole parent manually)?

futile avatar Sep 07 '16 21:09 futile

Sequences in XML are hard :) That's why I went with only accepting the xsi:type method for now.

What do you think about the following structure, similar to how it's done for inner text by using $value?

enum Obj { ObjA, ObjB }
struct Parent {
    #[serde(rename="$sequence")]
    data: Vec<Obj>,
}

oli-obk avatar Sep 08 '16 08:09 oli-obk

@oli-obk Looks good to me! As a full feature, I would expect this method to also extend to cases like the following:

enum Obj { ObjA, ObjB }
enum Foo { FooA, FooB }
struct Parent {
    #[serde(rename="$sequence")]
    data_obj: Vec<Obj>,
    #[serde(rename="$sequence")]
    data_foo: Vec<Foo>,
}

to deserialize xml like:

<parent>
  <objA/>
  <fooA/>
  <fooB/>
  <objB/>
  <objA/>
  <fooA/>
</parent>

With the obvious semantics. Maybe a new attribute like #[serde(sequence)] would be appropiate for this case. Using #[serde(rename="$sequence")] looks kind of like a hack, even though it's only different syntax for the same result.

futile avatar Sep 08 '16 22:09 futile

That's not possible in serde without first parsing the entire subtree. I don't really want to support interleaved sequences.

oli-obk avatar Sep 09 '16 09:09 oli-obk

In that case the solution you proposed sounds good to me. I also don't have a use case for the interleaved example I wrote, so it's not something I actually encountered the need for.

futile avatar Sep 09 '16 09:09 futile