Zurück zu den Updates
New releaseAug 9, 2026

xmloxide v0.5.0

Eine reine Rust-Neuumsetzung von libxml2

Teilen

xmloxide

CI crates.io docs.rs License: MIT MSRV

Eine reine Rust-Neuimplementierung von libxml2 — dem De-facto-Standard für XML/HTML-Parsing-Bibliotheken in der Open-Source-Welt.

libxml2 wurde im Dezember 2025 offiziell für ungepflegt erklärt und weist bekannte Sicherheitslücken auf. xmloxide zielt darauf ab, ein speichersicherer, leistungsstarker Ersatz zu sein, der die gleichen Konformitätstestsuiten besteht.

Funktionen

  • Speichersicher — Arena-basierter Baum ohne unsafe in der öffentlichen API
  • Konform — 100% Bestehensquote der W3C-XML-Konformitätstestsuite (1727/1727 anwendbare Tests)
  • Fehlerbehandlung — fehlerhafte XML-Daten parsen und trotzdem einen nutzbaren Baum erzeugen, genau wie libxml2
  • Mehrere Parsing-APIs — DOM-Baum, SAX2-Streaming, XmlReader-Pull, Push/inkrementell
  • HTML-Parser — fehlertolerantes HTML-4.01-Parsen mit automatischem Schließen und void-Elementen
  • WHATWG-HTML5-Parser — vollständiger HTML Living Standard-Tokenizer und Baumkonstruktor (8810/8810 html5lib-Tests bestanden)
  • HTML5-Streaming — SAX-ähnliche Callback-API für HTML5 (html5::sax), die den Tokenizer umschließt, ohne einen DOM-Baum zu erstellen
  • CSS-Selektoren — Abfrage von Elementen mit vertrauter CSS-Syntax (css::select) inklusive Kombinatoren, Pseudoklassen und schnellem #id-Lookup
  • XPath 1.0+ — vollständiger Ausdrucksparser und -auswerter mit allen Kernfunktionen von XPath 1.0 sowie wichtigen XPath-2.0-Funktionen (matches(), replace(), tokenize(), upper-case(), lower-case(), abs(), min(), max() und mehr)
  • Validierung — DTD-, RelaxNG-, XML-Schema-(XSD)- und ISO-Schematron-Validierung (ISO/IEC 19757-3)
  • Serde-Integration — optionales serde-Feature für XML-(De-)Serialisierung von/nach Rust-Typen
  • Asynchrones Parsen — optionales async-Feature zum Parsen von tokio::io::AsyncRead-Quellen
  • Kanonisches XML — C14N 1.0 und Exclusive-C14N-Serialisierung
  • XInclude — Dokumenteninklusionsverarbeitung
  • XML-Kataloge — OASIS-XML-Kataloge zur URI-Auflösung
  • xmllint-CLI — Kommandozeilenwerkzeug zum Parsen, Validieren und Abfragen von XML
  • Zero-Copy wo möglich — String-Interning für schnelle Vergleiche
  • Kein globaler Zustand — jedes Document ist in sich abgeschlossen und Send + Sync
  • C/C++-FFI — vollständige C-API mit Header-Datei (include/xmloxide.h) zur Einbettung in C/C++-Projekte
  • Minimale Abhängigkeiten — nur encoding_rs (die Bibliothek hat keine weiteren Abhängigkeiten; clap ist nur CLI-spezifisch)

Schnellstart

use xmloxide::Document;

let doc = Document::parse_str("<root><child>Hello</child></root>").unwrap();
let root = doc.root_element().unwrap();
assert_eq!(doc.node_name(root), Some("root"));
assert_eq!(doc.text_content(root), "Hello");

Serialisierung

use xmloxide::Document;
use xmloxide::serial::serialize;

let doc = Document::parse_str("<root><child>Hello</child></root>").unwrap();
let xml = serialize(&doc);
assert_eq!(xml, "<root><child>Hello</child></root>");

XPath-Abfragen

use xmloxide::Document;
use xmloxide::xpath::{evaluate, XPathValue};

let doc = Document::parse_str("<library><book><title>Rust</title></book></library>").unwrap();
let root = doc.root_element().unwrap();
let result = evaluate(&doc, root, "count(book)").unwrap();
assert_eq!(result.to_number(), 1.0);

SAX2-Streaming

use xmloxide::sax::{parse_sax, SaxHandler, DefaultHandler};
use xmloxide::parser::ParseOptions;

struct MyHandler;
impl SaxHandler for MyHandler {
    fn start_element(&mut self, name: &str, _: Option<&str>, _: Option<&str>,
                     _: &[(String, String, Option<String>, Option<String>)]) {
        println!("Element: {name}");
    }
}

parse_sax("<root><child/></root>", &ParseOptions::default(), &mut MyHandler).unwrap();

HTML-Parsing

use xmloxide::html::parse_html;

let doc = parse_html("<p>Hello <br> World").unwrap();
let root = doc.root_element().unwrap();
assert_eq!(doc.node_name(root), Some("html"));

CSS-Selektoren

use xmloxide::css::select;
use xmloxide::Document;

let doc = Document::parse_str(r#"<div><p class="intro">Hello</p><p>World</p></div>"#).unwrap();
let root = doc.root_element().unwrap();
let intros = select(&doc, root, "p.intro").unwrap();
assert_eq!(intros.len(), 1);
assert_eq!(doc.text_content(intros[0]), "Hello");

HTML5-Parsing (WHATWG)

use xmloxide::html5::parse_html5;

let doc = parse_html5("<p>Hello <b>world</b>").unwrap();
let root = doc.root_element().unwrap();
assert_eq!(doc.node_name(root), Some("html"));

Fragment-Parsing (der Algorithmus hinter innerHTML) wird ebenfalls unterstützt:

use xmloxide::html5::{parse_html5_with_options, Html5ParseOptions};

let opts = Html5ParseOptions {
    scripting: false,
    fragment_context: Some("body".to_string()),
};
let doc = parse_html5_with_options("<p>fragment</p>", &opts).unwrap();

HTML5-Streaming (SAX-ähnlich)

use xmloxide::html5::sax::{Html5SaxHandler, parse_html5_sax};

struct LinkExtractor { hrefs: Vec<String> }
impl Html5SaxHandler for LinkExtractor {
    fn start_element(&mut self, name: &str, attrs: &[(String, String)], _sc: bool) {
        if name == "a" {
            if let Some((_, href)) = attrs.iter().find(|(n, _)| n == "href") {
                self.hrefs.push(href.clone());
            }
        }
    }
}

let mut handler = LinkExtractor { hrefs: Vec::new() };
parse_html5_sax(r#"<a href="https://github.com/jonwiggins/xmloxide/blob/main/page">Link</a>"#, &mut handler);
assert_eq!(handler.hrefs, vec!["/page"]);

Fehlerbehandlung

use xmloxide::parser::{parse_str_with_options, ParseOptions};

let opts = ParseOptions::default().recover(true);
let doc = parse_str_with_options("<root><unclosed>", &opts).unwrap();
for diag in &doc.diagnostics {
    eprintln!("{}", diag);
}

CLI-Werkzeug

# Analysieren und hübsch ausgeben
xmllint --format document.xml

# Gegen ein Schema validieren
xmllint --schema schema.xsd document.xml
xmllint --relaxng schema.rng document.xml
xmllint --schematron schema.sch document.xml
xmllint --dtdvalid schema.dtd document.xml

# XPath-Abfrage
xmllint --xpath "//title" document.xml

# Kanonisches XML
xmllint --c14n document.xml

# HTML parsen
xmllint --html page.html

Modulübersicht

Kategorien