Add skipping of unrecognized elements (fixes #12)
This commit is contained in:
		
							parent
							
								
									df674965f8
								
							
						
					
					
						commit
						1f3de44a98
					
				| @ -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; | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -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 } | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user