use oxml::{Attribute, ExpandedName, NodeKind, parse};
const DOC: &str = r#"<?xml version="1.0"?>
<order xmlns:x="urn:example:x" id="A-1" x:ref="R-9" note="two & a half">
<line sku="ABC" qty="2"/>
<line sku="DEF" qty="1"/>
</order>
"#;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let doc = parse(DOC)?;
let order = doc.root_element().expect("a root element");
println!("id = {:?}", doc.attribute(order, "id"));
println!("ref = {:?}", doc.attribute(order, "ref"));
println!("gone = {:?}", doc.attribute(order, "nonexistent"));
println!("note = {:?}", doc.attribute(order, "note"));
println!("\n== every attribute ==");
for attr in doc.attributes(order) {
let Attribute { name, value } = attr;
let name = doc.name(*name).expect("interned");
match &name.namespace {
Some(uri) => println!(" {{{uri}}}{} = {value:?}", name.local),
None => println!(" {} = {value:?}", name.local),
}
}
println!("\n== by expanded name ==");
let wanted = ExpandedName::qualified("urn:example:x", "ref");
let found = doc
.attributes(order)
.into_iter()
.find(|a| doc.name(a.name) == Some(&wanted))
.map(|a| a.value.as_str());
println!(" {{urn:example:x}}ref = {found:?}");
println!("\n== as nodes ==");
for &id in doc.attribute_nodes(order) {
if let Some(NodeKind::Attr(a)) = doc.kind(id) {
let name = doc.name(a.name).expect("interned");
println!(" node {} is {}={:?}", id.index(), name.local, a.value);
}
println!(" text(): {:?}", doc.text(id));
}
println!("\n== a table of lines ==");
for &child in doc.children(order) {
if !doc.is_element(child) {
continue;
}
let sku = doc.attribute(child, "sku").unwrap_or("?");
let qty = doc.attribute(child, "qty").unwrap_or("0");
println!(" {sku} x{qty}");
}
Ok(())
}