1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
//! High performance XML reader/writer.
//!
//! ## Description
//!
//! - `Reader`: a low level xml pull-reader where buffer allocation/clearing is left to user
//! - `Writer`: a xml writer. Can be nested with readers if you want to transform xmls
//!
//! ## Examples
//!
//! ### Reader
//!
//! ```rust
//! use quick_xml::Reader;
//! use quick_xml::events::Event;
//!
//! let xml = r#"<tag1 att1 = "test">
//! <tag2><!--Test comment-->Test</tag2>
//! <tag2>
//! Test 2
//! </tag2>
//! </tag1>"#;
//!
//! let mut reader = Reader::from_str(xml);
//! reader.trim_text(true);
//!
//! let mut count = 0;
//! let mut txt = Vec::new();
//! let mut buf = Vec::new();
//!
//! // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
//! loop {
//! match reader.read_event(&mut buf) {
//! // for triggering namespaced events, use this instead:
//! // match reader.read_namespaced_event(&mut buf) {
//! Ok(Event::Start(ref e)) => {
//! // for namespaced:
//! // Ok((ref namespace_value, Event::Start(ref e)))
//! match e.name() {
//! b"tag1" => println!("attributes values: {:?}",
//! e.attributes().map(|a| a.unwrap().value)
//! .collect::<Vec<_>>()),
//! b"tag2" => count += 1,
//! _ => (),
//! }
//! },
//! // unescape and decode the text event using the reader encoding
//! Ok(Event::Text(e)) => txt.push(e.unescape_and_decode(&reader).unwrap()),
//! Ok(Event::Eof) => break, // exits the loop when reaching end of file
//! Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
//! _ => (), // There are several other `Event`s we do not consider here
//! }
//!
//! // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
//! buf.clear();
//! }
//! ```
//!
//! ### Writer
//!
//! ```rust
//! use quick_xml::Writer;
//! use quick_xml::events::{Event, BytesEnd, BytesStart};
//! use quick_xml::Reader;
//! use std::io::Cursor;
//! use std::iter;
//!
//! let xml = r#"<this_tag k1="v1" k2="v2"><child>text</child></this_tag>"#;
//! let mut reader = Reader::from_str(xml);
//! reader.trim_text(true);
//! let mut writer = Writer::new(Cursor::new(Vec::new()));
//! let mut buf = Vec::new();
//! loop {
//! match reader.read_event(&mut buf) {
//! Ok(Event::Start(ref e)) if e.name() == b"this_tag" => {
//!
//! // crates a new element ... alternatively we could reuse `e` by calling
//! // `e.into_owned()`
//! let mut elem = BytesStart::owned(b"my_elem".to_vec(), "my_elem".len());
//!
//! // collect existing attributes
//! elem.extend_attributes(e.attributes().map(|attr| attr.unwrap()));
//!
//! // copy existing attributes, adds a new my-key="some value" attribute
//! elem.push_attribute(("my-key", "some value"));
//!
//! // writes the event to the writer
//! assert!(writer.write_event(Event::Start(elem)).is_ok());
//! },
//! Ok(Event::End(ref e)) if e.name() == b"this_tag" => {
//! assert!(writer.write_event(Event::End(BytesEnd::borrowed(b"my_elem"))).is_ok());
//! },
//! Ok(Event::Eof) => break,
//! Ok(e) => assert!(writer.write_event(e).is_ok()),
//! // or using the buffer
//! // Ok(e) => assert!(writer.write(&buf).is_ok()),
//! Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
//! }
//! buf.clear();
//! }
//!
//! let result = writer.into_inner().into_inner();
//! let expected = r#"<my_elem k1="v1" k2="v2" my-key="some value"><child>text</child></my_elem>"#;
//! assert_eq!(result, expected.as_bytes());
//! ```
#![deny(missing_docs)]
#![recursion_limit = "1024"]
extern crate encoding_rs;
#[macro_use]
extern crate failure;
extern crate memchr;
mod errors;
mod escape;
pub mod events;
mod reader;
mod writer;
// reexports
pub use errors::{Error, Result};
pub use reader::Reader;
pub use writer::Writer;