1use crate::{Result, Tags};
2use quick_xml::{Reader, Writer, events::Event};
3use std::io::{BufRead, Write};
4
5pub fn clean_xml<R, W>(src: &mut Reader<R>, dest: &mut Writer<W>, rm_tags: &Tags) -> Result<()>
7where
8 R: BufRead,
9 W: Write,
10{
11 let mut buf = Vec::<u8>::new();
12 let mut rm_depth = 0usize;
13
14 loop {
15 match src.read_event_into(&mut buf) {
16 Ok(Event::Start(e)) => {
17 let tag = e.name().into_inner();
18 if rm_depth > 0 || rm_tags.contains(tag) {
19 rm_depth += 1;
20 } else {
21 dest.write_event(Event::Start(e))?;
22 }
23 }
24 Ok(Event::End(e)) => {
25 if rm_depth > 0 {
26 rm_depth -= 1;
27 } else {
28 dest.write_event(Event::End(e))?;
29 }
30 }
31 Ok(Event::Empty(e)) => {
32 let tag = e.name().into_inner();
33 if rm_depth == 0 && !rm_tags.contains(tag) {
34 dest.write_event(Event::Empty(e))?;
35 }
36 }
37 Ok(Event::Text(e)) => {
38 if rm_depth == 0 {
39 dest.write_event(Event::Text(e))?;
40 }
41 }
42 Ok(Event::Eof) => break,
43 Ok(e) => {
44 if rm_depth == 0 {
45 dest.write_event(e)?;
46 }
47 }
48 Err(e) => return Err(Box::new(e)),
49 }
50 buf.clear();
51 }
52
53 Ok(())
54}