pub struct Writer<W> { /* private fields */ }
Expand description
XML writer. Writes XML Event
s to a std::io::Write
implementor.
Examples
use quick_xml::events::{Event, BytesEnd, BytesStart};
use quick_xml::reader::Reader;
use quick_xml::writer::Writer;
use std::io::Cursor;
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()));
loop {
match reader.read_event() {
Ok(Event::Start(e)) if e.name().as_ref() == b"this_tag" => {
// crates a new element ... alternatively we could reuse `e` by calling
// `e.into_owned()`
let mut elem = BytesStart::new("my_elem");
// 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(e)) if e.name().as_ref() == b"this_tag" => {
assert!(writer.write_event(Event::End(BytesEnd::new("my_elem"))).is_ok());
},
Ok(Event::Eof) => break,
// we can either move or borrow the event to write, depending on your use-case
Ok(e) => assert!(writer.write_event(e).is_ok()),
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
}
}
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());
Implementations§
source§impl<W: AsyncWrite + Unpin> Writer<W>
impl<W: AsyncWrite + Unpin> Writer<W>
sourcepub async fn write_event_async<'a, E: AsRef<Event<'a>>>(
&mut self,
event: E
) -> Result<()>
Available on crate feature async-tokio
only.
pub async fn write_event_async<'a, E: AsRef<Event<'a>>>( &mut self, event: E ) -> Result<()>
async-tokio
only.Writes the given event to the underlying writer. Async version of Writer::write_event
.
sourcepub async fn write_indent_async(&mut self) -> Result<()>
Available on crate feature async-tokio
only.
pub async fn write_indent_async(&mut self) -> Result<()>
async-tokio
only.Manually write a newline and indentation at the proper level. Async version of
Writer::write_indent
.
This method will do nothing if Writer
was not constructed with Writer::new_with_indent
.
source§impl<W> Writer<W>
impl<W> Writer<W>
sourcepub fn new_with_indent(
inner: W,
indent_char: u8,
indent_size: usize
) -> Writer<W>
pub fn new_with_indent( inner: W, indent_char: u8, indent_size: usize ) -> Writer<W>
Creates a Writer
with configured indents from a generic writer.
sourcepub fn into_inner(self) -> W
pub fn into_inner(self) -> W
Consumes this Writer
, returning the underlying writer.
sourcepub fn create_element<'a, N>(&'a mut self, name: &'a N) -> ElementWriter<'_, W>where
N: 'a + AsRef<str> + ?Sized,
pub fn create_element<'a, N>(&'a mut self, name: &'a N) -> ElementWriter<'_, W>where N: 'a + AsRef<str> + ?Sized,
Provides a simple, high-level API for writing XML elements.
Returns an ElementWriter
that simplifies setting attributes and writing
content inside the element.
Example
use quick_xml::events::{BytesStart, BytesText, Event};
use quick_xml::writer::Writer;
use quick_xml::Error;
use std::io::Cursor;
let mut writer = Writer::new(Cursor::new(Vec::new()));
// writes <tag attr1="value1"/>
writer.create_element("tag")
.with_attribute(("attr1", "value1")) // chain `with_attribute()` calls to add many attributes
.write_empty()?;
// writes <tag attr1="value1" attr2="value2">with some text inside</tag>
writer.create_element("tag")
.with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter()) // or add attributes from an iterator
.write_text_content(BytesText::new("with some text inside"))?;
// writes <tag><fruit quantity="0">apple</fruit><fruit quantity="1">orange</fruit></tag>
writer.create_element("tag")
// We need to provide error type, because it is not named somewhere explicitly
.write_inner_content::<_, Error>(|writer| {
let fruits = ["apple", "orange"];
for (quant, item) in fruits.iter().enumerate() {
writer
.create_element("fruit")
.with_attribute(("quantity", quant.to_string().as_str()))
.write_text_content(BytesText::new(item))?;
}
Ok(())
})?;
source§impl<W: Write> Writer<W>
impl<W: Write> Writer<W>
sourcepub fn write_bom(&mut self) -> Result<()>
pub fn write_bom(&mut self) -> Result<()>
Write a Byte-Order-Mark character to the document.
Example
use quick_xml::events::{BytesStart, BytesText, Event};
use quick_xml::writer::Writer;
use quick_xml::Error;
use std::io::Cursor;
let mut buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
writer.write_bom()?;
writer
.create_element("empty")
.with_attribute(("attr1", "value1"))
.write_empty()
.expect("failure");
assert_eq!(
std::str::from_utf8(&buffer).unwrap(),
"\u{FEFF}<empty attr1=\"value1\"/>"
);
sourcepub fn write_event<'a, E: AsRef<Event<'a>>>(&mut self, event: E) -> Result<()>
pub fn write_event<'a, E: AsRef<Event<'a>>>(&mut self, event: E) -> Result<()>
Writes the given event to the underlying writer.
sourcepub fn write_indent(&mut self) -> Result<()>
pub fn write_indent(&mut self) -> Result<()>
Manually write a newline and indentation at the proper level.
This can be used when the heuristic to line break and indent after any
Event
apart from Text
fails such as when a Start
occurs directly
after Text
.
This method will do nothing if Writer
was not constructed with new_with_indent
.
sourcepub fn write_serializable<T: Serialize>(
&mut self,
tag_name: &str,
content: &T
) -> Result<(), DeError>
Available on crate feature serialize
only.
pub fn write_serializable<T: Serialize>( &mut self, tag_name: &str, content: &T ) -> Result<(), DeError>
serialize
only.Write an arbitrary serializable type
Note: If you are attempting to write XML in a non-UTF-8 encoding, this may not be safe to use. Rust basic types assume UTF-8 encodings.
#[derive(Debug, PartialEq, Serialize)]
struct MyData {
question: String,
answer: u32,
}
let data = MyData {
question: "The Ultimate Question of Life, the Universe, and Everything".into(),
answer: 42,
};
let mut buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
let start = BytesStart::new("root");
let end = start.to_end();
writer.write_event(Event::Start(start.clone()))?;
writer.write_serializable("my_data", &data)?;
writer.write_event(Event::End(end))?;
assert_eq!(
std::str::from_utf8(&buffer)?,
r#"<root>
<my_data>
<question>The Ultimate Question of Life, the Universe, and Everything</question>
<answer>42</answer>
</my_data>
</root>"#
);