Add skipping of unrecognized elements (fixes #12)

This commit is contained in:
Dmitry Samoylov 2020-02-13 19:34:47 +07:00
parent df674965f8
commit 1f3de44a98
3 changed files with 67 additions and 1 deletions

View File

@ -88,6 +88,16 @@ impl<'de, R: Read> Deserializer<R> {
Ok(next_event) 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) { pub fn set_map_value(&mut self) {
self.is_map_value = true; self.is_map_value = true;
} }

View File

@ -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#"
<?xml version="1.0" encoding="utf-8"?>
<Struct>
<id>54</id>
<SubStruct>
<id>86</id>
</SubStruct>
</Struct>
"#,
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#"
<?xml version="1.0" encoding="utf-8"?>
<Struct id="54">
<SubStruct id="86" />
</Struct>
"#,
Struct,
Struct { id: 54 }
);
}

View File

@ -440,23 +440,36 @@ pub fn parse(
#field_visitors #field_visitors
#init_unused #init_unused
let mut depth = 0;
loop { loop {
let event = reader.peek()?.to_owned(); let event = reader.peek()?.to_owned();
match event { match event {
XmlEvent::StartElement{ref name, ref attributes, ..} => { XmlEvent::StartElement{ref name, ref attributes, ..} => {
let mut skipped = false;
match name.local_name.as_str() { match name.local_name.as_str() {
#call_visitors #call_visitors
named_element => { named_element => {
let event = reader.next_event()?; let event = reader.next_event()?;
#write_unused #write_unused
if depth > 0 { // Don't skip root element
skipped = true;
reader.skip_element(|event| {
#write_unused
})?;
}
} }
// name => { // name => {
// return Err(format!("unknown key {}", name)) // return Err(format!("unknown key {}", name))
// } // }
} }
#attributes_loading if !skipped {
#attributes_loading
}
depth += 1;
} }
XmlEvent::EndElement{ref name} => { XmlEvent::EndElement{ref name} => {
if name.local_name == named_element { if name.local_name == named_element {
@ -465,6 +478,7 @@ pub fn parse(
} }
let event = reader.next_event()?; let event = reader.next_event()?;
#write_unused #write_unused
depth -= 1;
} }
XmlEvent::Characters(ref text_content) => { XmlEvent::Characters(ref text_content) => {
#set_text #set_text