العودة إلى التحديثات
New releaseAug 9, 2026

xmloxide v0.5.0

إعادة تنفيذ خالص بلغة Rust لمكتبة libxml2

مشاركة

xmloxide

CI crates.io docs.rs License: MIT MSRV

إعادة تنفيذ نقي بلغة Rust لمكتبة libxml2 — مكتبة تحليل XML/HTML القياسية الفعلية في عالم المصادر المفتوحة.

أصبحت libxml2 غير مدعومة رسميًا منذ ديسمبر 2025 مع مشاكل أمنية معروفة. تهدف xmloxide إلى أن تكون بديلاً آمنًا للذاكرة وعالي الأداء ينجح في نفس مجموعات اختبار المطابقة.

المميزات

  • آمن للذاكرة — شجرة قائمة على الساحة (arena) مع عدم وجود unsafe في الواجهة العامة
  • مطابق للمعايير — نسبة نجاح 100% في مجموعة اختبار مطابقة XML من W3C (1727/1727 اختبارًا قابلًا للتطبيق)
  • استرداد الأخطاء — تحليل XML غير صحيح مع الاستمرار في إنتاج شجرة قابلة للاستخدام، تمامًا مثل libxml2
  • واجهات برمجة تحليل متعددة — شجرة DOM، دفق SAX2، سحب XmlReader، تحليل دفعي/متزايد
  • محلل HTML — تحليل HTML 4.01 متسامح مع الأخطاء مع الإغلاق التلقائي والعناصر الفارغة
  • محلل WHATWG HTML5 — محلل كامل وفقًا لمعيار HTML الحي (8810/8810 من اختبارات html5lib-tests ناجحة)
  • دفق HTML5 — واجهة رد نداء شبيهة بـ SAX لـ HTML5 (html5::sax) تغلف المحلل دون بناء شجرة DOM
  • محددات CSS — استعلام عن العناصر باستخدام صيغة CSS مألوفة (css::select) تشمل الأدوات المركبة والفئات الزائفة والبحث السريع بـ #id
  • XPath 1.0+ — محلل ومقيّم تعبيرات كامل مع جميع دوال XPath 1.0 الأساسية بالإضافة إلى دوال XPath 2.0 رئيسية (matches()، replace()، tokenize()، upper-case()، lower-case()، abs()، min()، max()، والمزيد)
  • التحقق — التحقق من DTD، RelaxNG، XML Schema (XSD)، و ISO Schematron (ISO/IEC 19757-3)
  • التكامل مع Serde — ميزة اختيارية serde لتسلسل/إلغاء تسلسل XML من/إلى أنواع Rust
  • التحليل غير المتزامن — ميزة اختيارية async للتحليل من مصادر tokio::io::AsyncRead
  • XML قانوني — تسلسل C14N 1.0 و Exclusive C14N
  • XInclude — معالجة تضمين المستندات
  • كتالوجات XML — كتالوجات XML من OASIS لحل URIs
  • أداة CLI xmllint — أداة سطر أوامر لتحليل XML والتحقق منه والاستعلام عنه
  • نسخ صفري حيثما أمكن — تخزين السلاسل مؤقتًا لإجراء مقارنات سريعة
  • بدون حالة عمومية — كل Document مستقل ويمكن إرساله (Send) ومشاركته بين الخيوط (Sync)
  • FFI بلغة C/C++ — واجهة C كاملة مع ملف رأس (include/xmloxide.h) للتضمين في مشاريع C/C++
  • أقل عدد من التبعيات — فقط encoding_rs (المكتبة ليس لها تبعيات أخرى؛ clap مخصص لسطر الأوامر فقط)

بداية سريعة

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");

التسلسل

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

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

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

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

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 (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"));

كما أن تحليل القطع (الخوارزمية التي تقف وراء innerHTML) مدعوم:

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 (شبيه بـ SAX)

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"]);

استرداد الأخطاء

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);
}

أداة سطر الأوامر

# تحليل وطباعة منسقة
xmllint --format document.xml

# تحقق مقابل مخطط
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
xmllint --xpath "//title" document.xml

# XML قانوني
xmllint --c14n document.xml

# تحليل HTML
xmllint --html page.html

نظرة عامة على الوحدات

الوحدةالوصف
treeشجرة DOM قائمة على الساحة (Document، NodeId، NodeKind)
parserمحلل تنازلي متكرر لـ XML 1.0 مع استرداد الأخطاء
parser::pushمحلل دفعي/متزايد للإدخال المجزأ
htmlمحلل HTML 4.01 متسامح مع الأخطاء
html5محلل WHATWG HTML الحي (محلل الرموز + باني الشجرة)
html5::saxواجهة دفق شبيهة بـ SAX لـ HTML5 (لا تُبنى شجرة DOM)
cssمحرك محددات CSS للاستعلام عن أشجار المستندات
saxمحلل دفق يعتمد على الأحداث بتقنية SAX2
readerواجهة تحليل سحب XmlReader
serialمسلسلات XML وHTML وHTML5، بالإضافة إلى XML قانوني (C14N)
xpathمحلل ومقيّم تعبيرات XPath 1.0+
validation::dtdتحليل DTD والتحقق منه
validation::relaxngالتحقق من مخطط RelaxNG
validation::xsdالتحقق من XML Schema (XSD)
validation::schematronالتحقق القائم على قواعد ISO Schematron
serde_xmlتسلسل/إلغاء تسلسل Serde لـ XML (ميزة اختيارية serde)
async_xmlتحليل غير متزامن عبر tokio::io::AsyncRead (ميزة اختيارية async)
xincludeتضمين المستندات وفقًا لـ XInclude 1.0
catalogكتالوجات XML من OASIS لحل URIs
encodingكشف ترميز الأحرف وتحويله
ffiروابط FFI بلغة C/C++ (include/xmloxide.h)

الأداء

الفئات