Rust XML parser implementation for SAX interface: xml_sax
In this example "start element" and "end element" events are counted. You can see there is a handler that stores variables. We add xml_sax::ContentHandler
interface to this handler and run parser. The beauty of having an simple interface is that more parser libraries can implement it. So there is an opportunity of code reuse across the community.
Note that you can find more examples under tests
directory.
```rust extern crate xmloxide; extern crate xmlsax;
use std::io::BufReader; use std::fs::File; use std::time::Instant;
use xml_oxide::sax::*;
use std::rc::Rc; use std::cell::RefCell;
struct MySaxHandler2 { pub counter: usize, pub endcounter: usize, pub charcounter: usize, }
impl xmlsax::ContentHandler for MySaxHandler2 { fn startdocument(&mut self) {}
fn end_document(&mut self) {}
fn start_element(
&mut self,
uri: &str,
local_name: &str,
qualified_name: &str,
attributes: &xml_sax::SAXAttributes,
) {
self.counter = self.counter + 1;
// print every 10000th element name
if self.counter % 10000 == 0 {
println!("%10000 start {}", qualified_name);
}
//println!("qname: {}", qualified_name);
for attr in attributes.iter() {
//println!("iter attr: {}", attr.get_value());
}
}
fn end_element(&mut self, uri: &str, local_name: &str, qualified_name: &str) {
self.end_counter += 1;
}
fn characters(&mut self, characters: &str) {}
}
fn main() { let now = Instant::now();
let f: File = match File::open("test/simple.xml") {
Ok(file) => file,
Err(e) => {
println!("{}", e);
return ();
}
};
let mut reader = BufReader::new(f);
let my_sax_handler2 = MySaxHandler2 {
counter: 0,
end_counter: 0,
char_counter: 0,
};
let mut sax_parser = SaxParser::new();
let handler = Rc::new(RefCell::new(my_sax_handler2));
sax_parser.set_content_handler(handler.clone());
sax_parser.parse(&mut reader);
println!("START EVENT COUNT:{}", handler.borrow().counter);
println!("END EVENT COUNT:{}", handler.borrow().end_counter);
println!("TOTAL CHARS:{}", handler.borrow().char_counter);
println!(
"secs: {} nanos: {}",
now.elapsed().as_secs(),
now.elapsed().subsec_nanos()
);
}
```