Merge pull request #41 from DmitrySamoylov/fix-element-clashes

Add skipping of unrecognized elements (fixes #12)
This commit is contained in:
Marc-Antoine ARNAUD 2020-02-16 11:24:21 +01:00 committed by GitHub
commit c122b66052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 1 deletions

View File

@ -88,6 +88,16 @@ impl<'de, R: Read> Deserializer<R> {
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;
}

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
#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