#[cfg(feature = "async")]
use oxml::stream::{AsyncReader, Event};
#[cfg(feature = "async")]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let xml_payload = r#"<?xml version="1.0" encoding="UTF-8"?>
<inventory store="London Flagship">
<item sku="OX-001" category="books">
<title>The Rust Programming Language</title>
<price currency="GBP">35.00</price>
<stock>42</stock>
</item>
<item sku="OX-002" category="electronics">
<title>Mechanical Keyboard</title>
<price currency="GBP">120.00</price>
<stock>15</stock>
</item>
</inventory>"#;
let cursor = std::io::Cursor::new(xml_payload.as_bytes());
let mut reader = AsyncReader::from_reader(cursor).await?;
let mut current_item_sku = None;
let mut item_count = 0;
println!("Starting asynchronous XML streaming event loop...\n");
while let Some(event) = reader.next_event().await? {
match event {
Event::StartElement {
name, attributes, ..
} => {
if name.local == "item" {
item_count += 1;
if let Some((_, sku)) =
attributes.iter().find(|(attr, _)| attr.local == "sku")
{
current_item_sku = Some(sku.clone());
}
} else if name.local == "title"
&& let Some(sku) = ¤t_item_sku
{
print!("Item [{sku}]: ");
}
}
Event::Text(text) => {
let trimmed = text.trim();
if !trimmed.is_empty() {
println!("{trimmed}");
}
}
Event::EndElement { name, .. } => {
if name.local == "item" {
current_item_sku = None;
}
}
Event::Comment(comment) => {
println!("Comment found: {comment}");
}
_ => {}
}
}
println!("\nSuccessfully streamed {item_count} items with AsyncReader.");
println!("Stopped at byte {}.", reader.offset());
let parts: &[(&str, &str)] = &[("greeting.ent", "hello")];
let doc = r#"<!DOCTYPE d [<!ENTITY g SYSTEM "greeting.ent">]><d>&g;</d>"#;
let mut reader =
AsyncReader::from_reader(std::io::Cursor::new(doc.as_bytes()))
.await?
.with_external(&parts);
while let Some(event) = reader.next_event().await? {
if let Event::Text(text) = event {
println!("External entity expanded to {text:?}.");
}
}
Ok(())
}
#[cfg(not(feature = "async"))]
fn main() {
println!("Asynchronous streaming requires the 'async' feature.");
println!("Run with: cargo run --example stream_async --features async");
}