Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
xmloxide — libxml2の純粋なRust再実装 | Kitploit
ツール/GitHubGitHub/jonwiggins/xmloxide
静的分析脆弱性分析コード分析ファジングバイナリ解析学習と教育厳選リソースラボと実践
GitHubjonwiggins/xmloxide

xmloxide

libxml2の純粋なRust再実装

リポジトリを見る
84831ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

xmloxide

CI crates.io docs.rs License: MIT MSRV

libxml2 の純Rust再実装 — オープンソース世界で事実上の標準XML/HTMLパースライブラリです。

libxml2は2025年12月に公式メンテナンス終了となり、既知のセキュリティ問題を抱えています。xmloxideは、メモリ安全かつ高性能で、同じ適合性テストスイートを通過する代替品を目指します。

特徴

  • メモリ安全 — アリーナベースのツリーで、公開APIにunsafeを一切含みません
  • 適合性 — W3C XML適合性テストスイートで100%の合格率(1727/1727の該当テスト)
  • エラーリカバリ — libxml2と同様に、不正なXMLでも解析して利用可能なツリーを生成
  • 複数のパースAPI — DOMツリー、SAX2ストリーミング、XmlReaderプル、プッシュ/インクリメンタル
  • HTMLパーサー — 自動クローズや空要素をサポートしたエラー耐性のあるHTML 4.01パーサー
  • WHATWG HTML5パーサー — 完全なHTML Living Standardトークナイザーとツリービルダー(8810/8810のhtml5lib-tests合格)
ツールをダウンロード
  • HTML5ストリーミング — DOMツリーを構築せずにトークナイザーをラップするSAXライクなコールバックAPI(html5::sax)
  • 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フィーチャーで、Rust型とのXML (逆)シリアライズ
  • 非同期パース — オプションのasyncフィーチャーで、tokio::io::AsyncReadソースからのパース
  • Canonical XML — C14N 1.0およびExclusive C14Nシリアライズ
  • XInclude — ドキュメントインクルード処理
  • XMLカタログ — URI解決のためのOASIS XMLカタログ
  • xmllint CLI — XMLのパース、検証、クエリを行うコマンドラインツール
  • 可能な限りゼロコピー — 文字列インターンによる高速比較
  • グローバル状態なし — 各Documentは自己完結型でSend + Sync
  • C/C++ FFI — C/C++プロジェクトに埋め込むための完全なC APIとヘッダーファイル(include/xmloxide.h)
  • 最小限の依存関係 — encoding_rsのみ(ライブラリは他に依存関係なし。clapはCLIのみ)
  • クイックスタート

    root@kitploit:~
    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");
    

    シリアライズ

    root@kitploit:~
    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クエリ

    root@kitploit:~
    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ストリーミング

    root@kitploit:~
    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パース

    root@kitploit:~
    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セレクター

    root@kitploit:~
    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)

    root@kitploit:~
    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の背後にあるアルゴリズム)もサポートしています:

    root@kitploit:~
    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ライク)

    root@kitploit:~
    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"]);
    

    エラーリカバリ

    root@kitploit:~
    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ツール

    root@kitploit:~
    # パースしてプリティプリント
    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
    
    # Canonical 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パーサー
    html5WHATWG HTML Living Standardパーサー(トークナイザー+ツリービルダー)
    html5::saxHTML5用のストリーミングSAXライクAPI(DOMツリーは構築しない)
    cssドキュメントツリーをクエリするCSSセレクターエンジン
    saxSAX2ストリーミングイベント駆動パーサー
    readerXmlReaderプルベースのパースAPI
    serialXML、HTML、HTML5シリアライザー、およびCanonical XML (C14N)
    xpathXPath 1.0+式パーサーと評価器
    validation::dtdDTDパースと検証
    validation::relaxngRelaxNGスキーマ検証
    validation::xsdXML Schema (XSD) 検証
    validation::schematronISO Schematronルールベース検証
    serde_xmlSerde XML (逆)シリアライズ(オプションのserdeフィーチャー)
    async_xmltokio::io::AsyncRead経由の非同期パース(オプションのasyncフィーチャー)
    xincludeXInclude 1.0ドキュメントインクルード
    catalogURI解決のためのOASIS XMLカタログ
    encoding文字エンコーディング検出と変換
    ffiC/C++ FFIバインディング(include/xmloxide.h)

    パフォーマンス

    パースのスループットはlibxml2と競合します — ほとんどのドキュメントで3-4%以内、SVGでは12%高速です。シリアライズはアリーナベースのツリー設計のおかげで1.5-2.4倍高速です。XPathはすべてのベンチマークで1.1-2.7倍高速です。

    パース:

    ドキュメントサイズxmloxidelibxml2結果
    Atomフィード4.9 KB26.7 µs (176 MiB/s)25.5 µs (184 MiB/s)~4%低速
    SVG描画6.3 KB58.5 µs (103 MiB/s)65.6 µs (92 MiB/s)12%高速
    Maven POM11.5 KB76.9 µs (142 MiB/s)74.2 µs (148 MiB/s)~4%低速
    XHTMLページ10.2 KB69.5 µs (139 MiB/s)61.5 µs (157 MiB/s)~13%低速
    大(374 KB)374 KB2.15 ms (169 MiB/s)2.08 ms (175 MiB/s)~3%低速

    シリアライズ:

    ドキュメントサイズxmloxidelibxml2結果
    Atomフィード4.9 KB11.3 µs17.5 µs1.5倍高速
    Maven POM11.5 KB20.1 µs47.5 µs2.4倍高速
    大(374 KB)374 KB614 µs1397 µs2.3倍高速

    XPath:

    式xmloxidelibxml2結果
    単純パス (//entry/title)1.51 µs1.63 µs8%高速
    属性述語 (//book[@id])5.91 µs15.99 µs2.7倍高速
    count()関数1.09 µs1.67 µs1.5倍高速
    string()関数1.32 µs1.77 µs1.3倍高速

    主要な最適化:アリーナベースのツリーによる高速シリアライズ、文字検証のためのバイトレベルの事前チェック、一括テキストスキャン、名前解析のためのASCII高速パス、ゼロコピー要素名分割、インラインエンティティ解決、XPath // ステップの融合軸展開、インラインツリーアクセサ、子/子孫軸の名前テスト高速パス。

    root@kitploit:~
    # ベンチマークを実行(libxml2システムライブラリが必要)
    cargo bench --features bench-libxml2 --bench comparison_bench
    

    テスト

    • 1078の単体テスト(全モジュール)
    • 138のFFIテスト(SAX、Schematron、CSSを含む完全なC API表面をカバー)
    • libxml2互換性スイート — 119/119テスト合格(100%)。XMLパース、名前空間、エラー検出、HTMLパースをカバー
    • W3C XML適合性テストスイート — 1727/1727の該当テスト合格(100%)
    • html5lib-tests — 7032/7032トークナイザーテスト + 1778/1778ツリー構築テスト(100%)
    • 統合テスト — 実世界のXML/HTMLドキュメント、エッジケース、エラーリカバリをカバー
    root@kitploit:~
    cargo test --all-features
    

    C/C++ FFI

    xmloxideは、C/C++プロジェクト(Chromium、ゲームエンジン、または現在libxml2を使用している任意のコードベース)に埋め込むためのC互換APIを提供します。

    root@kitploit:~
    # 共有ライブラリ+静的ライブラリをビルド(付属のMakefileを使用)
    make
    
    # または個別にビルド:
    make shared   # .so / .dylib / .dll
    make static   # .a / .lib
    
    # Cの例をビルドして実行
    make example
    
    root@kitploit:~
    #include "xmloxide.h"
    
    xmloxide_document *doc = xmloxide_parse_str("<root>Hello</root>");
    uint32_t root = xmloxide_doc_root_element(doc);
    char *name = xmloxide_node_name(doc, root);   // "root"
    char *text = xmloxide_node_text_content(doc, root); // "Hello"
    
    xmloxide_free_string(name);
    xmloxide_free_string(text);
    xmloxide_free_doc(doc);
    

    完全なAPI — ツリーのナビゲーションと変更、XPath評価、シリアライズ(プレーンおよびプリティプリント)、HTML/HTML5パース、DTD/RelaxNG/XSD/Schematron検証、C14N、SAXストリーミング、XmlReader、プッシュパーサー、XMLカタログ — は include/xmloxide.h で宣言されています。

    libxml2からの移行

    libxml2xmloxide (Rust)xmloxide (C FFI)
    xmlReadMemoryDocument::parse_strxmloxide_parse_str
    xmlReadFileDocument::parse_filexmloxide_parse_file
    xmlParseDocDocument::parse_bytesxmloxide_parse_bytes
    htmlReadMemoryhtml::parse_htmlxmloxide_parse_html
    (HTML5パース)html5::parse_html5—
    (HTML5フラグメント / innerHTML)html5::parse_html5_with_options—
    (HTML5ストリーミング)html5::sax::parse_html5_sax—
    (CSSセレクター / querySelector)css::select—
    xmlFreeDoc(Documentをドロップ)xmloxide_free_doc
    xmlDocGetRootElementdoc.root_element()xmloxide_doc_root_element
    xmlNodeGetContentdoc.text_content(id)xmloxide_node_text_content
    xmlNodeSetContentdoc.set_text_content(id, s)xmloxide_set_text_content
    xmlGetPropdoc.attribute(id, name)xmloxide_node_attribute
    xmlSetPropdoc.set_attribute(...)xmloxide_set_attribute
    xmlNewNodedoc.create_node(...)

    スレッド安全性: libxml2とは異なり、xmloxideにはグローバル状態がありません。各Documentは自己完結型でSend + Syncです。FFIレイヤーは最後のエラーメッセージにスレッドローカルストレージを使用しており、各スレッドは独自のエラー状態を持ちます。初期化やクリーンアップ関数は必要ありません。

    ファジング

    xmloxideはセキュリティテスト用のファズターゲットを含んでいます:

    root@kitploit:~
    # cargo-fuzzをインストール(nightlyが必要)
    cargo install cargo-fuzz
    
    # ファズターゲットを実行
    cargo +nightly fuzz run fuzz_xml_parse
    cargo +nightly fuzz run fuzz_html_parse
    cargo +nightly fuzz run fuzz_html5_parse
    cargo +nightly fuzz run fuzz_html5_fragment
    cargo +nightly fuzz run fuzz_xpath
    cargo +nightly fuzz run fuzz_roundtrip
    cargo +nightly fuzz run fuzz_sax
    cargo +nightly fuzz run fuzz_reader
    cargo +nightly fuzz run fuzz_push
    cargo +nightly fuzz run fuzz_validation
    cargo +nightly fuzz run fuzz_schematron
    

    ビルド

    root@kitploit:~
    cargo build
    cargo test
    cargo clippy --all-targets --all-features -- -D warnings
    cargo bench
    

    最小サポートRustバージョン: 1.81

    制限事項

    • XML 1.1非対応 — xmloxideはXML 1.0(第5版)のみを実装しています。XML 1.1はほとんど使用されておらず、計画もありません。
    • XSLT非対応 — XSLTは別の仕様(libxslt)であり、対象外です。
    • HTMLパーサー — HTML 4.01パーサー(libxml2の動作に準拠)と完全なWHATWG HTML5パーサーの両方を提供しています。HTML5パーサーはhtml5lib-testsの100%に合格しています。
    • プッシュパーサーは内部でバッファリング — プッシュ/インクリメンタルパーサーAPI(PushParser)は現在、すべてのプッシュされたデータをバッファリングし、finish()で完全なパースを行います。libxml2のxmlParseChunkのような真のストリーミングではありません。メモリ制約のある大規模ドキュメント処理の代替として、SAXストリーミング(XMLの場合はparse_sax、HTML5の場合はhtml5::sax::parse_html5_sax)が利用可能です。
    • XPath namespace::軸 — namespace::軸は、スコープ内の名前空間が一致する場合に要素ノードを返します(個別の名前空間ノードを具体化するのではなく)。これは属性軸と同じパターンに従います。

    コントリビュート

    開発環境のセットアップとガイドラインについては CONTRIBUTING.md を参照してください。

    変更履歴

    バージョン履歴については CHANGELOG.md を参照してください。

    ライセンス

    MIT

    xmloxide_create_element
    xmlNewTextdoc.create_node(Text{..})xmloxide_create_text
    xmlAddChilddoc.append_child(p, c)xmloxide_append_child
    xmlAddPrevSiblingdoc.insert_before(ref, c)xmloxide_insert_before
    xmlUnlinkNodedoc.remove_node(id)xmloxide_remove_node
    xmlCopyNodedoc.clone_node(id, deep)xmloxide_clone_node
    xmlGetIDdoc.element_by_id(s)xmloxide_element_by_id
    xmlDocDumpMemoryserial::serialize(&doc)xmloxide_serialize
    xmlDocDumpFormatMemoryserial::serialize_with_optionsxmloxide_serialize_pretty
    htmlDocDumpMemoryserial::html::serialize_htmlxmloxide_serialize_html
    xmlC14NDocDumpMemoryserial::c14n::canonicalizexmloxide_canonicalize
    xmlXPathEvalExpressionxpath::evaluatexmloxide_xpath_eval
    xmlValidateDtdvalidation::dtd::validatexmloxide_validate_dtd
    xmlRelaxNGValidateDocvalidation::relaxng::validatexmloxide_validate_relaxng
    xmlSchemaValidateDocvalidation::xsd::validate_xsdxmloxide_validate_xsd
    (Schematron検証)validation::schematron::validate_schematronxmloxide_validate_schematron
    xmlXIncludeProcessxinclude::process_xincludesxmloxide_process_xincludes
    xmlLoadCatalogCatalog::parsexmloxide_parse_catalog
    xmlSAX2... コールバックsax::SaxHandlerトレイトxmloxide_sax_parse
    xmlTextReaderReadreader::XmlReaderxmloxide_reader_read
    xmlCreatePushParserCtxtparser::PushParserxmloxide_push_parser_new
    xmlParseChunkPushParser::pushxmloxide_push_parser_push