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
Section titled “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
Section titled “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 namespace-aware _ns counterpart. Instead of a prefix:tag
string, these take the local name plus a
NamespaceDeclaration, so the
match is resolved against the document’s live namespace scope regardless of the
exact prefix used in the source:
use draviavemal_xml_rs::NamespaceDeclaration;
const TEST_NS: NamespaceDeclaration = NamespaceDeclaration::new( "http://example.org/test", "t",);
// Match a "book" element in the test namespace, whatever prefix it uses.let first = document.find_first_child_ns(root_id, "book", &TEST_NS)?;let all = document.find_all_child_ns(root_id, "book", &TEST_NS)?;Find by attribute
Section titled “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) take the local attribute name plus a
NamespaceDeclaration and match by resolved URI.
Walk the tree structurally
Section titled “Walk the tree structurally”When you don’t have a tag to search for, walk parents, children and siblings by id:
let parent_id = document.get_parent(book_id)?; // Option<NodeId>let children = document.get_children(root_id)?; // Option<Vec<NodeId>>let first = document.get_first_child_element(root_id)?;let last = document.get_last_child_element(root_id)?;let next = document.get_next_sibling(book_id)?; // Option<NodeId>let prev = document.get_previous_sibling(book_id)?;To search the entire subtree (not just direct children) for a tag, use
get_elements_by_tag_name / get_elements_by_tag_name_ns:
let all_titles = document.get_elements_by_tag_name(root_id, "title")?;Read attributes
Section titled “Read attributes”let element = document.get_element(book_id)?;
// By local nameif let Some(attr) = element.get_attribute("id") { println!("{}", attr.get_value());}
// By namespace declaration (alias-independent, matched by URI)if let Some(attr) = element.get_attribute_ns("lang", &TEST_NS) { println!("{}", attr.get_value());}
// Or read just the valuelet id = element.get_attribute_value("id"); // Option<&str>let lang = element.get_attribute_value_ns("lang", &TEST_NS);Read content (text, elements, comments)
Section titled “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 elementslet child_count = element.get_child_element_count()?;For plain-text extraction there are shortcuts: get_element_text_value()
returns the first direct text node, get_text_content() concatenates every
direct text node, and document.get_element_text_content(id) joins the text of
the whole subtree.