Skip to content

Building & Editing

You can build a document programmatically and serialize it, or edit a parsed tree in place. Mutating methods end in _mut and most return the new node’s NodeId.

use draviavemal_xml_rs::{XmlDocument, XmlAttribute};
let mut document = XmlDocument::new();
let root_id = document.create_root_element_mut(
"root",
Some(vec![XmlAttribute::new("version".into(), "1.0".into())]),
)?;
let child_id = document.append_child_element_mut(
root_id,
"child",
Some(vec![XmlAttribute::new("id".into(), "child1".into())]),
)?;

Prefer the _ns variants for round-trip-safe namespaces: pass the local name and a NamespaceDeclaration, and the crate resolves (or declares) the alias against the live scope for you.

use draviavemal_xml_rs::{XmlDocument, NamespaceDeclaration};
const MAIN_NS: NamespaceDeclaration = NamespaceDeclaration::new(
"http://schemas.openxmlformats.org/spreadsheetml/2006/main", "main",
);
let mut document = XmlDocument::new();
let root_id = document.create_root_element_ns_mut("workbook", &MAIN_NS, None)?;
let sheets_id = document.append_child_element_ns_mut(root_id, "sheets", &MAIN_NS, None)?;

When element order matters, insert relative to a sibling tag instead of always appending:

MethodInserts the new element…
insert_child_element_after_last_tag_mutafter the last child with the given (raw) tag
insert_child_element_before_first_tag_mutbefore the first child with the given (raw) tag
insert_child_element_after_last_tag_ns_mutafter the last child matching a namespaced reference tag
insert_child_element_before_first_tag_ns_mutbefore the first child matching a namespaced reference tag
let id = document.insert_child_element_before_first_tag_mut(
root_id, "header", "body", None,
)?;
use draviavemal_xml_rs::{NamespaceDeclaration, XmlAttribute};
const XML_NS: NamespaceDeclaration = NamespaceDeclaration::new(
"http://www.w3.org/XML/1998/namespace", "xml",
);
let element = document.get_element_mut(child_id)?;
element.add_text_mut("Hello World")?;
element.add_comments_mut("a note")?;
element.add_attribute_mut("lang", "en")?;
// Add-or-replace instead of erroring on a duplicate name
element.add_replace_attribute_mut("lang", "fr")?;
// Namespaced attribute (declares the alias in scope if needed)
element.add_attribute_ns_mut("space", &XML_NS, "preserve")?;
// Set the initial attribute list (only when the element has none yet)
element.set_attribute_mut(vec![XmlAttribute::new("id".into(), "c1".into())])?;
// Remove attributes
element.remove_attribute_mut("lang"); // by name
element.remove_attribute_ns_mut("space", &XML_NS); // by namespace declaration
element.clear_attribute_mut()?; // remove all (returns the count)

Operate on the document to remove nodes or empty an element:

// Remove all children of an element but keep the element itself
document.clear_element_content_mut(child_id)?;
// Remove an element and its entire subtree
document.remove_element_mut(child_id)?;
use draviavemal_xml_rs::{XmlSerializer, SerializeOptions};
let bytes = XmlSerializer::xml_tree_to_vec(&document)?;
// or write straight to disk
XmlSerializer::xml_doc_tree_to_file(&document, "out.xml")?;
// Optimize namespaces (hoist to lowest common ancestor, drop unused)
let options = SerializeOptions { optimize_namespaces: true };
let compact = XmlSerializer::xml_tree_to_vec_with(&document, &options)?;