Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

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

xmloxide

libxml2の純粋なRust再実装

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

人気

すべて見る →

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

すべてのツールを探索

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

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

[![CI](https://github.com/jonwiggins/xmloxide/actions/workflows/ci.yml/badge.svg)](https://github.com/jonwiggins/xmloxide/actions/workflows/ci.yml)
[![crates.io](https://img.shields.io/crates/v/xmloxide.svg)](https://crates.io/crates/xmloxide)
[![docs.rs](https://docs.rs/xmloxide/badge.svg)](https://docs.rs/xmloxide)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![MSRV](https://img.shields.io/badge/MSRV-1.81-blue.svg)](https://www.rust-lang.org)

[libxml2](https://gitlab.gnome.org/GNOME/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](https://html.spec.whatwg.org/)トークナイザーとツリービルダー(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のみ)

## クイックスタート

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

### シリアライズ

```rust
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クエリ

```rust
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ストリーミング

```rust
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パース

```rust
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セレクター

```rust
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)

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

```rust
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ライク)

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

### エラーリカバリ

```rust
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ツール

```sh
# パースしてプリティプリント
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パーサー |
| `html5` | WHATWG HTML Living Standardパーサー(トークナイザー+ツリービルダー) |
| `html5::sax` | HTML5用のストリーミングSAXライクAPI(DOMツリーは構築しない) |
| `css` | ドキュメントツリーをクエリするCSSセレクターエンジン |
| `sax` | SAX2ストリーミングイベント駆動パーサー |
| `reader` | XmlReaderプルベースのパースAPI |
| `serial` | XML、HTML、HTML5シリアライザー、およびCanonical 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` | URI解決のためのOASIS XMLカタログ |
| `encoding` | 文字エンコーディング検出と変換 |
| `ffi` | C/C++ FFIバインディング(`include/xmloxide.h`) |

## パフォーマンス

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

**パース:**

| ドキュメント | サイズ | xmloxide | libxml2 | 結果 |
|----------|------|----------|---------|--------|
| Atomフィード | 4.9 KB | 26.7 µs (176 MiB/s) | 25.5 µs (184 MiB/s) | ~4%低速 |
| SVG描画 | 6.3 KB | 58.5 µs (103 MiB/s) | 65.6 µs (92 MiB/s) | **12%高速** |
| Maven POM | 11.5 KB | 76.9 µs (142 MiB/s) | 74.2 µs (148 MiB/s) | ~4%低速 |
| XHTMLページ | 10.2 KB | 69.5 µs (139 MiB/s) | 61.5 µs (157 MiB/s) | ~13%低速 |
| 大(374 KB) | 374 KB | 2.15 ms (169 MiB/s) | 2.08 ms (175 MiB/s) | ~3%低速 |

**シリアライズ:**

| ドキュメント | サイズ | xmloxide | libxml2 | 結果 |
|----------|------|----------|---------|--------|
| Atomフィード | 4.9 KB | 11.3 µs | 17.5 µs | **1.5倍高速** |
| Maven POM | 11.5 KB | 20.1 µs | 47.5 µs | **2.4倍高速** |
| 大(374 KB) | 374 KB | 614 µs | 1397 µs | **2.3倍高速** |

**XPath:**

| 式 | xmloxide | libxml2 | 結果 |
|------------|----------|---------|--------|
| 単純パス (`//entry/title`) | 1.51 µs | 1.63 µs | **8%高速** |
| 属性述語 (`//book[@id]`) | 5.91 µs | 15.99 µs | **2.7倍高速** |
| `count()`関数 | 1.09 µs | 1.67 µs | **1.5倍高速** |
| `string()`関数 | 1.32 µs | 1.77 µs | **1.3倍高速** |

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

```sh
# ベンチマークを実行(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ドキュメント、エッジケース、エラーリカバリをカバー

```sh
cargo test --all-features
```

## C/C++ FFI

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

```sh
# 共有ライブラリ+静的ライブラリをビルド(付属のMakefileを使用)
make

# または個別にビルド:
make shared   # .so / .dylib / .dll
make static   # .a / .lib

# Cの例をビルドして実行
make example
```

```c
#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`](https://github.com/jonwiggins/xmloxide/blob/main/include/xmloxide.h) で宣言されています。

## libxml2からの移行

| libxml2 | xmloxide (Rust) | xmloxide (C FFI) |
|---------|----------------|------------------|
| `xmlReadMemory` | `Document::parse_str` | `xmloxide_parse_str` |
| `xmlReadFile` | `Document::parse_file` | `xmloxide_parse_file` |
| `xmlParseDoc` | `Document::parse_bytes` | `xmloxide_parse_bytes` |
| `htmlReadMemory` | `html::parse_html` | `xmloxide_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` |
| `xmlDocGetRootElement` | `doc.root_element()` | `xmloxide_doc_root_element` |
| `xmlNodeGetContent` | `doc.text_content(id)` | `xmloxide_node_text_content` |
| `xmlNodeSetContent` | `doc.set_text_content(id, s)` | `xmloxide_set_text_content` |
| `xmlGetProp` | `doc.attribute(id, name)` | `xmloxide_node_attribute` |
| `xmlSetProp` | `doc.set_attribute(...)` | `xmloxide_set_attribute` |
| `xmlNewNode` | `doc.create_node(...)` | `xmloxide_create_element` |
| `xmlNewText` | `doc.create_node(Text{..})` | `xmloxide_create_text` |
| `xmlAddChild` | `doc.append_child(p, c)` | `xmloxide_append_child` |
| `xmlAddPrevSibling` | `doc.insert_before(ref, c)` | `xmloxide_insert_before` |
| `xmlUnlinkNode` | `doc.remove_node(id)` | `xmloxide_remove_node` |
| `xmlCopyNode` | `doc.clone_node(id, deep)` | `xmloxide_clone_node` |
| `xmlGetID` | `doc.element_by_id(s)` | `xmloxide_element_by_id` |
| `xmlDocDumpMemory` | `serial::serialize(&doc)` | `xmloxide_serialize` |
| `xmlDocDumpFormatMemory` | `serial::serialize_with_options` | `xmloxide_serialize_pretty` |
| `htmlDocDumpMemory` | `serial::html::serialize_html` | `xmloxide_serialize_html` |
| `xmlC14NDocDumpMemory` | `serial::c14n::canonicalize` | `xmloxide_canonicalize` |
| `xmlXPathEvalExpression` | `xpath::evaluate` | `xmloxide_xpath_eval` |
| `xmlValidateDtd` | `validation::dtd::validate` | `xmloxide_validate_dtd` |
| `xmlRelaxNGValidateDoc` | `validation::relaxng::validate` | `xmloxide_validate_relaxng` |
| `xmlSchemaValidateDoc` | `validation::xsd::validate_xsd` | `xmloxide_validate_xsd` |
| (Schematron検証) | `validation::schematron::validate_schematron` | `xmloxide_validate_schematron` |
| `xmlXIncludeProcess` | `xinclude::process_xincludes` | `xmloxide_process_xincludes` |
| `xmlLoadCatalog` | `Catalog::parse` | `xmloxide_parse_catalog` |
| `xmlSAX2...` コールバック | `sax::SaxHandler`トレイト | `xmloxide_sax_parse` |
| `xmlTextReaderRead` | `reader::XmlReader` | `xmloxide_reader_read` |
| `xmlCreatePushParserCtxt` | `parser::PushParser` | `xmloxide_push_parser_new` |
| `xmlParseChunk` | `PushParser::push` | `xmloxide_push_parser_push` |

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

## ファジング

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

```sh
# 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
```

## ビルド

```sh
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](https://github.com/jonwiggins/xmloxide/blob/main/CONTRIBUTING.md) を参照してください。

## 変更履歴

バージョン履歴については [CHANGELOG.md](https://github.com/jonwiggins/xmloxide/blob/main/CHANGELOG.md) を参照してください。

## ライセンス

MIT
ツールをダウンロード