The tinyxml2 crate supports no_std builds that rely on the alloc crate for
dynamic memory (Vec, String, Box). It does not target bare-metal
core-only environments — a global allocator must be present.
The std feature is enabled by default. Disable it for embedded kernels,
RTOS environments, or custom targets where the standard library is unavailable.
Note
This page focuses on embedded / non-WASM no_std targets. For
WebAssembly-specific details (Emscripten, WASI SDK, browser host boundary),
see architecture/wasm.md.
[dependencies]
tinyxml2 = { version = "1", default-features = false }Disabling default-features removes the std feature flag. The crate then
applies #![no_std] and links against alloc exclusively.
If you are building a no_std binary crate (not just a library), you must also
provide:
// src/main.rs or src/lib.rs of the consuming crate
#![no_std]
extern crate alloc;
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
// Example: use `embedded-alloc`, `wee_alloc`, or a custom allocator
// #[global_allocator]
// static ALLOCATOR: MyAllocator = MyAllocator;#![no_std]
extern crate alloc;
use tinyxml2::Document;
fn parse_and_extract(xml: &str) -> Option<()> {
let mut doc = Document::parse(xml).ok()?;
let root = doc.first_child_element(doc.root(), Some("config"))?;
// Read an attribute
let version = doc
.element_ref(root)?
.attribute("version")
.unwrap_or("unknown");
// -- snip: use `version` via a no_std-compatible output like defmt or serial
// Serialize back to compact XML (always available, returns alloc::string::String)
let compact = doc.to_string_compact();
// -- snip: send `compact` over UART, defmt, log buffer, etc.
Some(())
}All in-memory parsing and DOM operations work without std:
Document::parse,Document::parse_str,Document::parse_bytes,Document::parse_bytes_mut- DOM creation, mutation, and traversal (
NodeId, iterators,NodeRef,ElementRef) - Entity encode/decode
XmlVisitortrait andDocument::acceptDocument::to_string,Document::to_string_compactXmlPrinter(push-based streaming serialiser)Handle/HandleMutnavigation wrappers
| API | default-features = true (std) |
default-features = false (no_std) |
|---|---|---|
Document::parse / parse_str / parse_bytes / parse_bytes_mut |
✅ | ✅ |
Document::load_file / load_file_mut |
✅ | ❌ |
Document::save_file / save_file_compact |
✅ | ❌ |
Document::save_writer / save_writer_compact |
✅ | ❌ |
Document::to_string / to_string_compact |
✅ | ✅ |
| DOM mutation, iterators, visitors | ✅ | ✅ |
XmlPrinter |
✅ | ✅ |
XmlError::Io variant |
✅ | ❌ |
impl std::error::Error for XmlError |
✅ | ❌ |
impl From<std::io::Error> for XmlError |
✅ | ❌ |
The six file-oriented methods (load_file, load_file_mut, save_file,
save_file_compact, save_writer, save_writer_compact) and the
XmlError::Io variant are compiled only when the std feature is active. Their
signatures reference std::path::Path and std::io::Write, which are
unavailable without the standard library.
-
A global allocator is required. The DOM stores node names, attribute values, text content, and child lists in
StringandVecfromalloc.core-only (no heap) targets are not supported. -
No file I/O.
Document::load_fileandDocument::save_fileneed thestdfeature. UseDocument::parse_bytes/to_stringand let the application layer handle loading bytes from a filesystem, flash, or network. -
No
std::io::Writestreaming.Document::save_writerandsave_writer_compactarestd-only. Useto_string/to_string_compactor theXmlPrinterstreaming builder instead. -
No
std::error::Errorimpl. Thestd::error::Errortrait implementation forXmlErroris absent withoutstd. UseXmlError::code()(returnsu32) or match on variants directly for error handling. -
All Cargo examples require
std. The registered[[example]]targets are executables and needfn main(). The code patterns insideexamples/wasm_parse.rsare portable and can be copied into ano_stdbinary crate.
The project's CI validates these build variants (wasm-build.yml):
# Native target, no_std (library only)
cargo build -p tinyxml2 --no-default-features --lib
# wasm32-unknown-unknown (browser), with and without std
cargo build -p tinyxml2 --target wasm32-unknown-unknown
cargo build -p tinyxml2 --no-default-features --target wasm32-unknown-unknown --lib
# wasm32-wasip1 (WASI hosts), with and without std
cargo build -p tinyxml2 --target wasm32-wasip1
cargo build -p tinyxml2 --no-default-features --target wasm32-wasip1 --libTo check against an embedded ARM target (requires rustup target add):
rustup target add thumbv7em-none-eabihf
cargo check -p tinyxml2 --no-default-features --target thumbv7em-none-eabihf --libReplace thumbv7em-none-eabihf with your target triple (e.g.
riscv32imac-unknown-none-elf, aarch64-unknown-none).
Tip
Use cargo check --lib for no_std targets — it validates the crate
compiles without needing a linker script, panic handler, or allocator in
scope. Full cargo build requires a binary entry point from a consuming
crate.