Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

tinyxml2-rs

A ground-up Rust implementation of the TinyXML2 API.

Build StatusCrates.iodocs.rsLicense: MITMSRV


What is tinyxml2-rs?

tinyxml2-rs is a native Rust implementation that provides behavioral and API compatibility with TinyXML-2. It treats TinyXML-2 as a behavioral specification — not as source code to translate.

Key Architectural Advantages

  • 100% Safe Rust Core: The core tinyxml2 crate enforces #![forbid(unsafe_code)]. Memory safety is statically guaranteed by the compiler.
  • Generational Arena DOM: Nodes are stored in a cache-friendly, allocation-efficient generational arena managed by Document. Use-after-free or dangling references return None rather than panicking or causing UB.
  • Strict FFI Isolation: Raw pointers and unsafe code are strictly confined to the tinyxml2-capi FFI boundary.
  • Zero Dependencies: The core parser has no external runtime crate dependencies.

Feature Matrix

Featuretinyxml2-rsC++ TinyXML2Advantages
Safety✅ 100% Safe Core❌ Raw Pointers (unsafe)Statically prevents use-after-free, memory leaks, and undefined behavior.
Memory Model✅ Generational Arena✅ Document OwnershipCache-friendly layouts, no dangling pointer issues.
API Parity✅ Complete✅ NativeFully mirrors element creation, querying, and hierarchy manipulation.
FFI Boundaries✅ Clear isolation❌ Built-in FFIThe FFI boundary isolates unsafe operations and catches panics.
Dependencies✅ Zero dependencies✅ Zero dependenciesHighly portable, fast compile times.
Error Handling✅ Idiomatic Result❌ Document error stateRust Result forces proper check-before-use patterns.

Quick Start

Rust Quick Start

Add the dependency to your Cargo.toml:

cargo add tinyxml2
use tinyxml2::Document;fnmain(){let xml = r#" <?xml version="1.0" encoding="UTF-8"?> <bookstore name="Sci-Fi Zone"> <book category="fiction"> <title lang="en">Dune</title> <author>Frank Herbert</author> <price>9.99</price> </book> </bookstore> "#;// Parse XMLlet doc = Document::parse(xml).expect("Failed to parse XML");// Navigate elementslet root = doc.root_element().expect("No root bookstore found");let bookstore = doc.element_ref(root).unwrap();println!("Store Name: {}", bookstore.attribute("name").unwrap());// Iterate child elementsfor book in doc.child_elements(root,Some("book")){let title_id = doc.first_child_element(book.id(),Some("title")).unwrap();let title = doc.element_ref(title_id).unwrap().text().unwrap();let price:f64 = doc.query_double_attribute(book.id(),"price").unwrap();println!("- Book: \"{}\" (${})", title, price);}}

C/C++ FFI Quick Start

Because Rust compiles to standard native dynamic and static libraries, tinyxml2-rs can be dropped directly into existing C and C++ projects as a binary replacement (producing libtinyxml2.so on Linux, libtinyxml2.dylib on macOS, or tinyxml2.dll on Windows).

By swapping in tinyxml2-capi, C/C++ developers get the memory safety of a Rust-backed parser under the hood. Furthermore, in upcoming releases, they will gain access to advanced features—like XPath queries and XML Namespace validation—that the original C++ TinyXML2 lacks, fully exposed through C FFI functions!

#include"tinyxml2_capi.h"#include<stdio.h>intmain() {
// Allocate documentTxDocument*doc=tx_document_new();
// Parseconstchar*xml="<config><theme>dark</theme></config>";
tx_document_parse(doc, xml);
// NavigateTxNodeIdroot=tx_root_element(doc);
TxNodeIdtheme=tx_first_child_element(doc, root, "theme");
printf("Theme: %s\n", tx_element_get_text(doc, theme));
// Cleanuptx_document_free(doc);
return0;
}

Workspace Structure

tinyxml2-rs/
├── crates/
│ ├── tinyxml2/ # Core library — DOM, parser, writer, entities, errors
│ ├── tinyxml2-capi/ # C FFI compatibility layer (cdylib + staticlib)
│ └── tinyxml2-bench/ # Benchmark harness (criterion)
├── tests/ # Integration & conformance tests
├── fuzz/ # Fuzz testing targets
├── benches/ # Benchmark data & fixtures
├── spec/ # TinyXML2 behavioral specification tests
└── examples/ # Usage examples

Minimum Supported Rust Version (MSRV)

Our MSRV policy guarantees compatibility with Rust 1.85.0 or newer. Changes to MSRV are considered breaking changes and will only occur with minor or major version bumps.


Release Status & Roadmap

Phase 8 — Documentation & Release (v1.0.0) ✅ Complete

MilestoneStatus
Project Scaffolding & Architecture✅ Complete
Error Types & Entity Handling✅ Complete
Arena-Based DOM Representation✅ Complete
Recursive Descent Parser✅ Complete
XML Writer (Compact + Pretty)✅ Complete
Visitor Pattern Traversal✅ Complete
C FFI Layer & Header Generation✅ Complete
Conformance Testing & Differential Fuzzing✅ Complete
Stable v1.0.0 Stable Release✅ Complete
Phase 9 — WASM & no_std Support (v1.1.0)✅ Complete
Phase 10 — XPath & Serde Integration (v1.2.0)🔲 Planned
Phase 11 — Advanced Perf & SIMD (v2.0.0)🔲 Planned

Additional Documentation


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request. We enforce the Contributor Covenant Code of Conduct.


License

Licensed under the MIT License. Copyright (c) 2026 Teebot.

About

A memory-safe, high-performance implementation of the TinyXML2 API written in Rust. Designed as a drop-in replacement for existing C/C++ projects while providing an idiomatic Rust API.

Resources

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages