New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Getting "invalid type: map, expected a sequence" when deserialising #390
Comments
Your XML can be mapped to that rust types: #[serde(rename_all = "PascalCase")]
struct Attribute {
name: String,
array: Array,
}
#[serde(rename_all = "PascalCase")]
struct Array {
data_object: Vec<DataObject>,
}
struct DataObject; This is the basic struct, you can use some technics described in #365 (comment) to get rid of intermediate Using Lines 1101 to 1136 in 532990d
|
@Mingun wow, thanks for getting back so quickly! Your code works, though as you say a simple adaptation to an Also, obviously the code I posted was a simplified example. I had been working with |
Custom <Array>
<DataObject .../>
<DataObject .../>
<DataObject .../><!-- only that element will buffered, overriding previous two -->
</Array> always represented in a buffer something like struct AnyName {
DataObject: Map<serde::Value, serde::Value>,
} So, then you try to deserialize struct Array<T> {
#[serde(rename = "DataObject")]
items: Vec<T>,
} from that content,
Internally, XML has only two types -- |
@Mingun thanks, that makes sense! I can't test this right now but I'll implement a custom deserialiser this evening. Thanks for your help! I'll close this issue. |
Greetings! So, no way to deserialize such XML into array without custom deserializer? |
I didn't even manage it with a custom deserialiser (though there may be some way that I missed). I ended up using quick-xml directly without the serde interface. Not as nice, since you have to implement serialisation and deserialisation separately, but raw quick-xml is actually very nice to use. |
@BratSinot, as I already said, you can use deserialize_with, but you still need an intermediate struct (but it can be defined inside the helper function) |
But I didn't see how it would help in such case: use serde::{Deserialize};
type BoxedStr = Box<str>;
type BoxedArray<T> = Box<[T]>;
#[derive(Debug, Deserialize)]
struct Data {
#[serde(rename = "Value")]
value: Value,
}
#[derive(Debug, Deserialize)]
struct Value {
#[serde(flatten)]
data: Actions,
}
#[derive(Debug, Deserialize)]
enum Actions {
Foo(Foo)
}
#[derive(Debug, Deserialize)]
struct Foo {
#[serde(rename = "Bar")]
bar: Bar,
}
#[derive(Debug, Deserialize)]
struct Bar {
#[serde(rename = "list")]
lists: BoxedArray<List>,
}
#[derive(Debug, Deserialize)]
pub struct List {
key: BoxedStr,
/*#[serde(flatten)]
values: BoxedArray<Value>*/
}
fn main() {
let xml_str = r#"<Data>
<Value>
<Foo>
<Bar>
<list key="section0">
<str value="value00" key="name00"/>
<str value="value01" key="name01"/>
</list>
<list key="section1">
<str value="value10" key="name10"/>
<str value="value11" key="name11"/>
</list>
</Bar>
</Foo>
</Value>
</Data>"#;
let data = quick_xml::de::from_str::<Data>(&xml_str).unwrap();
println!("{data:?}");
} |
@BratSinot, could you explain, what your final struct should like that? Topicstarter had a problem with removing intermediate structs, but in your case I don't understand what intermediate structs you want to eliminate |
Oh, sorry, missed that part. I thought I found problem that similar to mine =/ Final should be look like that: #[derive(Debug, Deserialize)]
struct Bar {
list: BoxedArray<ListItem>,
}
#[derive(Debug, Deserialize)]
pub struct ListItem {
key: BoxedStr,
values: BoxedArray<Value>
}
#[derive(Debug, Deserialize)]
pub enum Value {
#[serde(rename = "str")]
Str {
key: BoxedStr,
value: BoxedStr,
},
#[serde(rename = "str")]
Int {
key: BoxedStr,
value: u64,
},
} |
Change #[derive(Debug, Deserialize)]
pub struct ListItem {
key: BoxedStr,
#[serde(rename = "$value")]
values: BoxedArray<Value>
} and in should work on Minor question: why |
Because I don't needed mutability, and it uses lesser memory. Differences between |
Problem comes before #[derive(Debug, Deserialize)]
struct Bar {
#[serde(rename = "$value")]
list: BoxedArray<ListItem>,
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("missing field `$value`")', src/main.rs:60:58
stack backtrace: quick-xml = { git = "https://github.com/tafia/quick-xml.git", rev = "ebbcce0bf7ce4ebff6d50c79dd7dc5545b813a9e", features = ["serialize"] } |
In |
In that case, I got an error like Topicstarter: #[derive(Debug, Deserialize)]
struct Bar {
list: BoxedArray<ListItem>,
}
#[derive(Debug, Deserialize)]
pub struct ListItem {
key: BoxedStr,
/*#[serde(flatten)]
values: BoxedArray<Value>*/
}
Custom("invalid type: map, expected a sequence") |
Okey, seems I found the problem. #[derive(Debug, Deserialize)]
struct Value {
- #[serde(flatten)]
+ #[serde(rename = "$value")]
data: Actions,
} Seems what my next step will be to use this in my actual code =) Thanks a lot for your time and help! |
Hello. First of all, thanks for all the great work on this crate!
I'm trying to use the serde implementation to deserialise some XML that looks like this:
I would like to read this as:
Reading the
DataObject
as aTestObject
is easy since allDataObject
s in this context will beTestObject
s. TheExample
part was harder, but I got it working using anenum
and serde'stag
. However, I can't get theVec
to read correctly. I'm getting the errorCustom("invalid type: map, expected a sequence")
.To make sure there wasn't anything more complex causing a problem, I also created an
Array
object which only contains theVec
, but still get the same error.If I remove the parent
Example
object and just try to deserialise theArray
, it works as expected.I also tried serialising the data structure I want, and I get exactly the output I expect, but deserialising this output fails with the error. This is strange since (as far as I can tell) my serialisation logic is identical to my deserialisation logic.
I also have some code here that reproduces this last example:
Example
Would really appreciate any guidance with this!
The text was updated successfully, but these errors were encountered: