Migration Guide
Migrating from roxmltree to oxml
Retain 100% safe Rust while unlocking full XPath 1.0, mutable DOM operations, XSD validation, and unified tooling.
Why Upgrade?
roxmltree is a widely respected read-only XML parser in the Rust community known for its strict #![forbid(unsafe_code)] enforcement. However, many projects eventually hit structural limitations:
- Read-Only Wall:
roxmltreecannot modify nodes, insert children, update attributes, or serialize XML.oxmlprovides a mutable generational arena DOM. - Missing XPath 1.0:
roxmltreerequires manual recursive tree-walking functions.oxmlincludes a complete, compliant XPath 1.0 engine with standard functions and $O(1)$ integer predicate optimization. - No Schema Validation:
roxmltreeonly verifies XML well-formedness. Theoxmlecosystem includesxmlschemawith 95.2% W3C XSD conformance. - Beyond a Library:
oxmlships a CLI binary (oxml-cli), WebAssembly bindings (oxml-wasm), Language Server (oxml-lsp), and AI Model Context Protocol server (oxml-mcp).
Feature Comparison
| Capability | roxmltree | oxml Toolkit | Advantage |
|---|---|---|---|
Safety (#![forbid(unsafe_code)]) | Yes | Yes | Identical guarantee: zero unsafe blocks |
| DOM Tree Mutation | No (Read-only) | Yes | Generational slot recycling arena |
| XML Serialization & Formatting | No | Yes | Indentation and empty-element controls |
| XPath 1.0 Engine | No | Yes | 13 navigational axes + standard functions |
| W3C XML Schema (XSD) | No | Yes | 95.2% conformance over 35,942 tests |
| Zero-Copy Streaming | Slice borrowing | BorrowedEvent | Reader::next_borrowed() zero-copy slices |
| CLI & Shell Integration | No | Yes | oxml-cli pipe processing |
| AI / MCP Tools | No | Yes | 5 native tools for Claude & Cursor |
Code Migration
1. Document Parsing & Node Access
In roxmltree:
use Document;
let text = "<book id='b1'>Dune</book></library>" ;
let doc = parse?;
// Manual traversal required to find elements
for node in doc.descendants
In oxml:
use parse;
let text = "<book id='b1'>Dune</book></library>" ;
let doc = parse?;
// Direct traversal or high-level XPath query
let root = doc.root_element.unwrap;
let book = doc.children;
assert_eq!;
assert_eq!;
// Or with XPath 1.0:
let titles = doc.select?;
assert_eq!;
2. Modifying Nodes and Serializing (Impossible in roxmltree)
roxmltree cannot mutate document trees. In oxml:
use ;
let mut doc = parse?;
let root = doc.root_element.unwrap;
// Create and append a new book element
let book = doc.create_element;
doc.set_attribute;
doc.append_child;
// Add text content
let text = doc.create_text;
doc.append_child;
// Serialize formatted output
let output = doc.serialize;
assert!;
3. Zero-Copy Streaming Borrowing
Both libraries support zero-allocation scanning. In oxml, Reader::next_borrowed() yields BorrowedEvent<'a> items that borrow string slices directly from the input buffer:
use ;
let mut reader = new?;
while let Some = reader.next_borrowed?