-
Notifications
You must be signed in to change notification settings - Fork 233
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
Skip intermediate nodes #365
Comments
I guess the only way to do this is to implement your own |
You can use fn unwrap_list<'de, D>(deserializer: D) -> Result<Vec<Entity>, D::Error>
where
D: Deserializer<'de>,
{
Ok(Entities::deserialize(deserializer)?.children)
}
#[derive(Deserialize, Debug)]
pub struct Response {
#[serde(rename = "Entities", deserialize_with = "unwrap_list")]
entities: Vec<Entity>,
} Example for JSON, but it also should work for quick-xml: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=79f164ac3654d4d9ab6826ff156ac937 |
Appreciate it! Thanks! |
I made this a bit more generic with a macro: use serde::{Deserialize, Serialize, Deserializer};
use quick_xml::de::{from_str, DeError};
#[derive(Debug, Deserialize, Serialize)]
struct InnerNestedDetail {
#[serde(rename="modification_date",default)]
modification_date: String, // String just for example
#[serde(rename="version",default)]
version: f32,
#[serde(rename="description",default)]
description: String,
}
#[derive(Debug, Deserialize, Serialize)]
struct InnerNested{
#[serde(rename = "Inner_Nested_Detail")]
details: Vec<InnerNestedDetail>
}
macro_rules! unwrap_vec {
( $($name:ident,$outer_struct:ident,$field:ident,$inner_struct:ident)* ) => {
$(
fn $name<'de,D>(deserializer:D) -> Result<Vec<$inner_struct>,D::Error>
where
D: Deserializer<'de>,
{
Ok($outer_struct::deserialize(deserializer)?.$field)
}
)*
}
}
unwrap_vec!(unwrap_inner_nested_vec,InnerNested,details,InnerNestedDetail);
#[derive(Debug, Deserialize, Serialize)]
pub struct OuterTag {
identifier: String,
version: f32,
#[serde(rename = "Inner_Nested", deserialize_with = "unwrap_inner_nested_vec")]
inner_nested: Vec<InnerNestedDetail>,
}
fn parse_xml(xml_string:&str) -> Result<OuterTag,DeError> {
let test: OuterTag = from_str(xml_string)?;
Ok(test)
}
fn main(){
let xml_string = "<Outer_Tag>
<identifier>Some Identifier</identifier>
<version>2.0</version>
<Inner_Nested>
<Inner_Nested_Detail>
<modification_date>2022-04-20</modification_date>
<version>1.0</version>
<description>Initial version.</description>
</Inner_Nested_Detail>
<Inner_Nested_Detail>
<modification_date>2022-05-20</modification_date>
<version>2.0</version>
<description>Modified version.</description>
</Inner_Nested_Detail>
</Inner_Nested>
</Outer_Tag>";
let result = parse_xml(xml_string).unwrap();
println!("{:#?}",result);
println!("\nInner Nested Details Vec:\n{:#?}",result.inner_nested);
} I figured it would be easier to use a macro if you had multiple structures that needed this functionality. It could probably have a better name |
Hi,
I have XML that has container/wrapper types around collections of nodes and I'd like to skip them when parsing, for example:
i.e it works when I provide a struct
Entities
as a container that holds children:But what I would really like to do is to eliminate the
struct Entities
and have aVec<Entity>
instead, i.e:How would one achieve that?
Thank you.
The text was updated successfully, but these errors were encountered: