3 个不稳定版本

0.2.1 2024年6月3日
0.2.0 2024年6月3日
0.1.2-pre-alpha2023年6月5日
0.1.1-pre-alpha 2023年6月3日
0.1.0-pre-alpha 2023年6月2日

#1205解析器实现

Download history 246/week @ 2024-05-31 48/week @ 2024-06-07 7/week @ 2024-06-14

189 每月下载量

MIT/Apache

200KB
5K SLoC

NomExML

Crates.io docs.rs Crates.io Crates.io (latest)


nom-xml 是一个使用 nom 解析器组合器 Crate 解析 XML 文档的 Crate。

这个 Crate 初始创建是为了能够解析以下 XML 模式,这在当时的其他 Rust XML 解析器中很麻烦,因为 Serde Crate 的限制。

<root>
    <header>
        <header_field1>Value1</header_field1>
        <header_field2>Value2</header_field2>
    </header>
    <body>
        <body_field1>BodyValue1</body_field1>
        <body_field2>BodyValue2</body_field2>
    </body>
    <header>
        <header_field1>Value1</header_field1>
        <header_field2>Value2</header_field2>
    </header>
    <body>
        <body_field1>BodyValue1</body_field1>
        <body_field2>BodyValue2</body_field2>
    </body>
</root>

它最终发展成尽可能接近实现 XML 1.0 规范 - 第五版。选择 Nom 是因为它具有组合器解析风格,这允许从最低级别到逐步解析整个文档的 XML 规范规则。要达到完全兼容性还有一段路要走,但最终目标是能够解析任何 XML 文档,根据模式进行验证,并写入兼容的 XML 文档。除非涉及复杂的外部实体,否则此 Crate 应该已经能够解析大多数 XML 文档。

关键数据结构

文档

这个枚举封装了构成 XML 文档的所有顶级类型。核心变体是 Element(Tag,Box<Document>,Tag) 类型,它允许递归解析嵌套标签及其内容。

pub enum Document {
    Prolog {
        xml_decl: Option<XmlDecl>,
        misc: Option<Vec<Misc>>,
        doc_type: Option<DocType>,
    },
    Element(Tag, Box<Document>, Tag),
    Content(Option<String>),
    Nested(Vec<Document>),
    Empty,
    EmptyTag(Tag),
    ProcessingInstruction(ProcessingInstruction),
    Comment(String),
    CDATA(String),
}

关键方法

Document::parse

解析整个 XML &str 的主要方式。

示例

use nom_xml::{parse::Parse, config::Config, Document};

fn main() {
    let xml = "<root><child>Content</child></root>";
    let (_, doc) = Document::parse(xml, Config::default()).unwrap();
    println!("{doc:?}");
}

输出

Element(
    Tag {
        name:
            Name {
                prefix: None,
                local_part: "root",
            },
        attributes: None,
        state: Start,
    },
    Nested([
        Element(
            Tag {
                name:
                    Name {
                        prefix: None,
                        local_part: "child",
                    },
                attributes: None,
                state: Start,
            },
            Content("Content"),
            Tag {
                name:
                    Name {
                        prefix: None,
                        local_part: "child",
                    },
                attributes: None,
                state: End,
            },
        ),
    ]),
    Tag {
        name:
            Name {
                prefix: None,
                local_part: "root",
            },
        attributes: None,
        state: End,
    },
)

Document::iter_with_depth

一个遍历 XML 树特定深度的方法。有关更多信息,请参阅 'extract_information` 示例


待办事项


任务 优先级 状态
实现完整的测试套件 🚧
实现所有 生产规则 🚧
添加从特定标签解析内容和子元素的能力
添加更好的错误处理
修复调试输出 中等 💭
添加对解析大型XML文档的流式处理
实现显示功能 💭
调查console在调试和显示输出格式化中的应用(页面接口?) 💭

依赖项

~5.5MB
~162K SLoC