Skip to content

Instantly share code, notes, and snippets.

@lwilli
Created March 11, 2021 17:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lwilli/14fb3178bd9adac3a64edfbc11f42e0d to your computer and use it in GitHub Desktop.
Save lwilli/14fb3178bd9adac3a64edfbc11f42e0d to your computer and use it in GitHub Desktop.
Prettify XML in Rust using the quick_xml library
use quick_xml::events::Event;
use quick_xml::{Reader, Writer};
/// Prettify XML by adding proper new lines and indentation.
///
/// This uses the quick_xml library (https://github.com/tafia/quick-xml) to read/parse the given
/// XML string and then write it to a string as indented XML. This isn't perfect and most likely
/// not the most efficient.
///
/// One strange behavior is that a closing element tag is not put on a new line if it follows a
/// comment and text, for example:
/// ```
/// <tag2>
/// <!--Comment-->Text</tag2>
/// ```
///
/// Performance:
/// On a large 66K line minified XML document, this takes about 2700ms.
/// For small XMLs, the time is negligible.
pub fn prettify_xml(xml: &str) -> String {
let mut buf = Vec::new();
let mut reader = Reader::from_str(xml);
reader.trim_text(true);
let mut writer = Writer::new_with_indent(Vec::new(), b' ', 2);
loop {
let ev = reader.read_event(&mut buf);
match ev {
Ok(Event::Eof) => break, // exits the loop when reaching end of file
Ok(event) => writer.write_event(event),
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
}
.expect("Failed to parse XML");
// If we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
buf.clear();
}
let result = std::str::from_utf8(&*writer.into_inner())
.expect("Failed to convert a slice of bytes to a string slice")
.to_string();
result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment