fb2_clean/
clean_xml.rs

1use crate::{Result, Tags};
2use quick_xml::{Reader, Writer, events::Event};
3use std::io::{BufRead, Write};
4
5/// Removes specified tags from an XML.
6pub 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}