diff --git a/yaserde/src/de/mod.rs b/yaserde/src/de/mod.rs index ef19789..bf8b38e 100644 --- a/yaserde/src/de/mod.rs +++ b/yaserde/src/de/mod.rs @@ -88,6 +88,16 @@ impl<'de, R: Read> Deserializer { Ok(next_event) } + pub fn skip_element(&mut self, mut cb: impl FnMut(&XmlEvent)) -> Result<(), String> { + let depth = self.depth; + + while self.depth >= depth { + cb(&self.next_event()?); + } + + Ok(()) + } + pub fn set_map_value(&mut self) { self.is_map_value = true; } diff --git a/yaserde/tests/deserializer.rs b/yaserde/tests/deserializer.rs index 6cfc2a9..6ac79bc 100644 --- a/yaserde/tests/deserializer.rs +++ b/yaserde/tests/deserializer.rs @@ -780,3 +780,45 @@ fn de_flatten() { } ); } + +#[test] +fn de_subitem_issue_12() { + #[derive(Default, PartialEq, Debug, YaDeserialize)] + pub struct Struct { + id: i32, + } + + convert_and_validate!( + r#" + + + 54 + + 86 + + + "#, + Struct, + Struct { id: 54 } + ); +} + +#[test] +fn de_subitem_issue_12_attributes() { + #[derive(Default, PartialEq, Debug, YaDeserialize)] + pub struct Struct { + #[yaserde(attribute)] + id: i32, + } + + convert_and_validate!( + r#" + + + + + "#, + Struct, + Struct { id: 54 } + ); +} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 7886979..662ce85 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -440,23 +440,36 @@ pub fn parse( #field_visitors #init_unused + let mut depth = 0; + loop { let event = reader.peek()?.to_owned(); match event { XmlEvent::StartElement{ref name, ref attributes, ..} => { + let mut skipped = false; match name.local_name.as_str() { #call_visitors named_element => { let event = reader.next_event()?; #write_unused + + if depth > 0 { // Don't skip root element + skipped = true; + reader.skip_element(|event| { + #write_unused + })?; + } } // name => { // return Err(format!("unknown key {}", name)) // } } - #attributes_loading + if !skipped { + #attributes_loading + } + depth += 1; } XmlEvent::EndElement{ref name} => { if name.local_name == named_element { @@ -465,6 +478,7 @@ pub fn parse( } let event = reader.next_event()?; #write_unused + depth -= 1; } XmlEvent::Characters(ref text_content) => { #set_text