extern crate xml_oxide;
use xml_oxide::{sax::parser::Parser, sax::Event};
use std::char;
struct MyCollectorSaxHandler {
start_counter: usize,
end_counter: usize,
start_el_name_vec: Vec<String>,
end_el_name_vec: Vec<String>,
characters_collected_vec: Vec<String>,
characters_buf: String,
comments_buf: String,
}
fn collect_with_parser<R: std::io::Read>(f: R) -> MyCollectorSaxHandler {
let mut data = MyCollectorSaxHandler {
start_counter: 0,
end_counter: 0,
start_el_name_vec: Vec::new(),
end_el_name_vec: Vec::new(),
characters_collected_vec: Vec::new(),
characters_buf: String::new(),
comments_buf: String::new(),
};
let mut p = Parser::from_reader(f);
loop {
let res = p.read_event();
match res {
Ok(event) => match event {
Event::StartElement(el) => {
data.start_counter = data.start_counter + 1;
data.start_el_name_vec.push(el.name.to_owned());
for _attr in el.attributes() {}
}
Event::EndElement(el) => {
data.end_counter += 1;
data.end_el_name_vec.push(el.name.to_owned());
}
Event::EndDocument => {
break;
}
Event::Characters(chars) => {
data.characters_buf.push_str(chars);
data.characters_collected_vec.push(chars.to_string());
}
Event::Cdata(chars) => {
data.characters_buf.push_str(chars);
}
Event::Reference(reference) => {
println!(
"raw: {:?} , resolved {:?}",
reference.raw, reference.resolved
);
match reference.resolved {
Some(resolved) => {
data.characters_buf.push_str(resolved);
}
None => {}
}
}
_ => {}
},
Err(_err) => {
break;
}
}
}
data
}
#[test]
fn test_basic() {
let s = String::from("<rootEl><value>5</value></rootEl>");
let data = collect_with_parser(s.as_bytes());
assert_eq!(data.start_counter, 2);
assert_eq!(data.end_counter, 2);
assert_eq!(data.start_el_name_vec.get(0).unwrap(), "rootEl");
println!("{:?}", data.characters_collected_vec);
assert_eq!(data.end_el_name_vec.get(0).unwrap(), "value");
assert_eq!(data.characters_collected_vec.get(0).unwrap(), "5");
}
#[test]
fn test_66_entity_ref() {
let c = char::from_u32(60).unwrap();
assert_eq!(c, '<');
let c2 = char::from_u32(u32::from_str_radix("0003C", 16).unwrap()).unwrap();
assert_eq!(c2, '<');
let s = String::from("<rootEl><value>1<2<3<4</value></rootEl>");
let data = collect_with_parser(s.as_bytes());
assert_eq!(data.characters_buf, "1<2<3<4");
}
#[test]
fn test_18_cdata() {
let s = String::from(
"<rootEl>1<2<3<4<![CDATA[ \
1<2<3<4]]><![CDATA[]]></rootEl>",
);
let data = collect_with_parser(s.as_bytes());
println!("{}", data.characters_buf);
assert_eq!(data.characters_buf, "1<2<3<4 1<2<3<4");
}
#[test]
fn test_15_comment_1() {
let s = String::from("<rootEl>comments<!--are ignored--><!---->.</rootEl>");
let data = collect_with_parser(s.as_bytes());
println!("{}", data.characters_collected_vec.get(0).unwrap());
assert_eq!(data.characters_buf, "comments.");
}
#[test]
#[should_panic]
fn test_15_comment_not_well_formed() {
let s = String::from(
"<rootEl>comments<!-- are not well formed with 3 \
hyphen at the end unless it is empty---><!---->.</rootEl>",
);
let data = collect_with_parser(s.as_bytes());
println!("{}", data.characters_buf);
assert_eq!(data.characters_buf, "comments.");
}