Skip to content

Navigating & Querying

Every node in an XmlDocument has a NodeId (a u32). You start from the root and look up elements by id.

Start at the root

let root_id = document.get_root_id();
let root = document.get_element(root_id)?;
println!("{}", root.get_tag()); // local name, e.g. "catalog"
println!("{}", root.get_tag_ns()); // namespaced, e.g. "t:catalog"

Find children

// First child with a given local tag → Option<NodeId>
if let Some(title_id) = document.find_first_child(book_id, "title")? {
let title = document.get_element(title_id)?;
}
// All children with a given tag → Option<Vec<NodeId>>
if let Some(book_ids) = document.find_all_child(root_id, "book")? {
println!("{} books", book_ids.len());
}

Each finder has a namespaced (_ns) counterpart that matches the full prefix:tag name instead of just the local name:

// Match "t:book" rather than any "book"
let first = document.find_first_child_ns(root_id, "t:book")?;
let all = document.find_all_child_ns(root_id, "t:book")?;

Find by attribute

// First child whose attribute matches → Option<NodeId>
if let Some(book_id) = document.find_first_by_attribute(root_id, "id", "bk101")? {
let book = document.get_element(book_id)?;
}
// All children whose attribute matches → Option<Vec<NodeId>>
if let Some(ids) = document.find_all_by_attribute(root_id, "type", "fiction")? {
println!("{} matches", ids.len());
}

Namespaced attribute variants (find_first_by_attribute_ns, find_all_by_attribute_ns) match the prefix:attr name.

Read attributes

let element = document.get_element(book_id)?;
// By local name
if let Some(attr) = element.get_attribute("id") {
println!("{}", attr.get_value());
}
// By namespaced name, e.g. "t:lang"
if let Some(attr) = element.get_attribute_ns("t:lang") {
println!("{}", attr.get_value());
}

Read content (text, elements, comments)

An element's children are a list of XmlElementContentType values. Match on the variant you care about:

use draviavemal_xml_rs::XmlElementContentType;
if let Some(contents) = element.get_child_contents() {
for content in contents {
match content {
XmlElementContentType::Text(text) => println!("text: {text}"),
XmlElementContentType::Comment(c) => println!("comment: {c}"),
XmlElementContentType::Element((id, tag, _ns)) => {
println!("child <{tag}> id={id}");
}
}
}
}
// Count only child elements
let child_count = element.get_child_element_count()?;