31 个版本 (19 个破坏性更新)

0.20.0 2024 年 5 月 23 日
0.19.0 2023 年 11 月 18 日
0.18.1 2023 年 9 月 30 日
0.18.0 2023 年 2 月 4 日
0.3.0 2018 年 10 月 29 日

#11 in 解析器实现

Download history 86235/week @ 2024-05-02 85255/week @ 2024-05-09 87449/week @ 2024-05-16 84129/week @ 2024-05-23 89477/week @ 2024-05-30 95561/week @ 2024-06-06 111793/week @ 2024-06-13 97704/week @ 2024-06-20 102458/week @ 2024-06-27 102408/week @ 2024-07-04 110270/week @ 2024-07-11 112580/week @ 2024-07-18 119127/week @ 2024-07-25 112557/week @ 2024-08-01 107347/week @ 2024-08-08 83100/week @ 2024-08-15

每月 441,339 次下载
用于 1,101 个 crate (148 直接使用)

MIT/Apache

165KB
4K SLoC

roxmltree

Build Status Crates.io Documentation Rust 1.60+

XML 文档表示为只读树。

// Find element by id.
let doc = roxmltree::Document::parse("<rect id='rect1'/>")?;
let elem = doc.descendants().find(|n| n.attribute("id") == Some("rect1"))?;
assert!(elem.has_tag_name("rect"));

为什么是只读的?

因为在某些情况下,你可能只需要从 XML 文档中检索一些数据。对于这种情况,我们可以进行很多优化。

解析行为

遗憾的是,XML 可以以多种不同的方式解析。 roxmltree 尝试模仿 Python 的 lxml 的行为。更多详细信息,请参阅 docs/parsing.md

替代方案

功能/包 roxmltree libxml2 xmltree sxd-document
元素命名空间解析 ~1
属性命名空间解析
实体引用 × ×
字符引用
属性-值规范化
注释
处理指令
UTF-8 BOM × ×
非 UTF-8 输入
完全 DTD 支持
位置保留2
HTML 支持
树修改
写入
unsafe
语言 Rust C Rust Rust
依赖项 0 - 2 2
测试版本 0.20.0 Apple 提供的 0.10.3 0.3.2
许可 MIT / Apache-2.0 MIT MIT MIT

图例

  • ✓ - 支持
  • × - 解析错误
  • ~ - 部分支持
  • nothing - 不支持

说明

  1. 无默认命名空间传播。
  2. roxmltree 保持所有节点和属性在原始文档中的位置,因此如果你需要,可以轻松检索它。有关详细信息,请参阅 examples/print_pos.rs

还有 elementtreetreexml 包,但它们已经废弃很长时间了。

性能

以下是一些将 roxmltree 与其他 XML 树库进行比较的基准测试。

test huge_roxmltree      ... bench:   2,997,887 ns/iter (+/- 48,976)
test huge_libxml2        ... bench:   6,850,666 ns/iter (+/- 306,180)
test huge_sdx_document   ... bench:   9,440,412 ns/iter (+/- 117,106)
test huge_xmltree        ... bench:  41,662,316 ns/iter (+/- 850,360)

test large_roxmltree     ... bench:   1,494,886 ns/iter (+/- 30,384)
test large_libxml2       ... bench:   3,250,606 ns/iter (+/- 140,201)
test large_sdx_document  ... bench:   4,242,162 ns/iter (+/- 99,740)
test large_xmltree       ... bench:  13,980,228 ns/iter (+/- 229,363)

test medium_roxmltree    ... bench:     421,137 ns/iter (+/- 13,855)
test medium_libxml2      ... bench:     950,984 ns/iter (+/- 34,099)
test medium_sdx_document ... bench:   1,618,270 ns/iter (+/- 23,466)
test medium_xmltree      ... bench:   4,315,974 ns/iter (+/- 31,849)

test tiny_roxmltree      ... bench:       2,522 ns/iter (+/- 31)
test tiny_libxml2        ... bench:       8,931 ns/iter (+/- 235)
test tiny_sdx_document   ... bench:      11,658 ns/iter (+/- 82)
test tiny_xmltree        ... bench:      20,215 ns/iter (+/- 303)

与流式XML解析器相比,roxmltree 的速度略慢于 quick-xml,但仍然比 xmlrs 快得多。请注意,流式解析器通常不提供适当的字符串转义、DTD解析和命名空间支持。

test huge_quick_xml      ... bench:   2,997,887 ns/iter (+/- 48,976)
test huge_roxmltree      ... bench:   3,147,424 ns/iter (+/- 49,153)
test huge_xmlrs          ... bench:  36,258,312 ns/iter (+/- 180,438)

test large_quick_xml     ... bench:   1,250,053 ns/iter (+/- 21,943)
test large_roxmltree     ... bench:   1,494,886 ns/iter (+/- 30,384)
test large_xmlrs         ... bench:  11,239,516 ns/iter (+/- 76,937)

test medium_quick_xml    ... bench:     206,232 ns/iter (+/- 2,157)
test medium_roxmltree    ... bench:     421,137 ns/iter (+/- 13,855)
test medium_xmlrs        ... bench:   3,975,916 ns/iter (+/- 44,967)

test tiny_quick_xml      ... bench:       2,233 ns/iter (+/- 70)
test tiny_roxmltree      ... bench:       2,522 ns/iter (+/- 31)
test tiny_xmlrs          ... bench:      17,155 ns/iter (+/- 429)

说明

基准测试是在 Apple M1 Pro 上进行的。您可以在 benches 目录中运行 cargo bench 来尝试运行基准测试。

  • 由于所有库都提供了不同的XML支持,因此基准测试有点没有意义。
  • 我们使用 rust-libxml 包装器crate对 libxml2 进行基准测试。

内存开销

roxmltree 尽可能使用最少的内存来允许解析非常大的(多GB)XML文件。

峰值内存使用量并不直接与文件大小相关,而是与文件中的节点和属性的数量相关。需要归一化(即分配)多少个属性。以及需要预处理的(即分配的)文本节点有多少。

roxmltree 从不分配元素和属性名称、处理指令和注释。

通过禁用 positions 功能,您可以为每个节点和属性节省8个字节。

平均而言,开销约为文件大小的6-8倍。例如,我们的1.1GB样本XML文件,在默认功能启用的情况下,峰值内存使用量为7.6GB RAM,当禁用 positions 时,内存使用量为6.8GB RAM。

安全性

  • 此库不能崩溃。任何崩溃都应被视为严重错误并报告。
  • 此库禁止 unsafe 代码。

API

此库使用基于迭代器的Rust惯用API。如果您更熟悉浏览器/JS DOM API,您可以查看 tests/dom-api.rs 以了解它如何映射到Rust API。

许可

许可为以下任一项

任选其一。

贡献

除非您明确表示,否则根据Apache-2.0许可证定义的,您有意提交的任何贡献,均应按上述方式双重许可,不得附加任何额外条款或条件。

无运行时依赖项

功能