Rust XML parser implementation for SAX interface: xml_sax
There is active development and soon the current API will change significantly. I'm changing the library to be a pull parser. I will update the the examples when the new version is ready.
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()
);
}
```