#xml #parser #events #reader #iterator #api #emitter

已撤销 rust-xml

使用旧的 Rust 2015

0.1.1 2014年11月21日
0.1.0 2014年11月12日

#22 in #emitter

130KB
2.5K SLoC

rust-xml,Rust 的 XML 库

Build Status

rust-xml 是 Rust 编程语言的 XML 库。它主要受到 Java 流式 XML API (StAX) 的启发。

该库目前包含类似于 StAX 事件读取器 的拉解析器。它提供迭代器 API,因此您可以利用 Rust 现有的迭代器库功能。

此解析器功能齐全,但是也有一些限制

  • 目前不支持除 UTF-8 之外的其他编码,因为没有可用的基于流的编码库;当(或如果)一个将可用时,我将尝试使用它;
  • 不支持 DTD 验证,<!DOCTYPE> 声明被完全忽略;因此也不支持自定义实体;内部 DTD 声明可能会引起解析错误;
  • 不执行属性值归一化,也不对换行符进行归一化。

除此之外,解析器尽量符合 XML-1.0 规范。

计划实施的内容(优先级最高)

  1. XML 发射器,即 StAX 事件写入器 的类似物,包括美观打印;
  2. 将解析结果转换为 DOM 树并将其序列化回 XML 文本;
  3. 类似 SAX 的基于回调的解析器(在拉解析器上实现相对简单);
  4. 某种测试基础设施;
  5. 更多便利功能,如过滤生成的事件;
  6. XML 标准要求的缺失功能(例如上述归一化);
  7. DTD 验证;
  8. (让我们梦想一下)XML Schema 验证。

希望 XML 发射器能够尽快实现。这将允许轻松进行流处理,例如,转换大型 XML 文档。

构建和使用

rust-xml 使用 Cargo,因此只需在您的项目清单中添加一个依赖项部分

[dependencies.rust-xml]
git = "https://github.com/netvl/rust-xml"

解析

xml::reader::EventReader 需要一个 Buffer 来读取。当合适的基于流的编码库可用时,它可能会切换到使用该库提供的任何字符流结构,但当前它是一个 Buffer。然而,有几个静态方法允许从字符串或字节数组创建解析器。

EventReader 的使用非常简单。只需提供一个 Buffer,然后创建一个事件迭代器

#![feature(globs)]

extern crate xml;

use std::io::File;
use std::io::BufferedReader;

use xml::reader::EventReader;
use xml::reader::events::*;

fn indent(size: uint) -> String {
    let mut result = String::with_capacity(size*4);
    for _ in range(0, size) {
        result.push_str("    ");
    }
    result
}

fn main() {
    let file = File::open(&Path::new("file.xml")).unwrap();
    let reader = BufferedReader::new(file);

    let mut parser = EventReader::new(reader);
    let mut depth = 0;
    for e in parser.events() {
        match e {
            StartElement { name, .. } => {
                println!("{}/{}", indent(depth), name);
                depth += 1;
            }
            EndElement { name } => {
                depth -= 1;
                println!("{}/{}", indent(depth), name);
            }
            Error(e) => {
                println!("Error: {}", e);
                break;
            }
            _ => {}
        }
    }
}

events() 应该只调用一次,也就是说,它返回的迭代器实例将始终使用相同的底层解析器(待办事项:制作消费迭代器)。文档解析可以正常结束或遇到错误结束。无论具体原因如何,解析过程将被停止,迭代器将正常终止。

您还可以通过解析器自己的 next() 方法更精细地控制何时从解析器中拉取下一个事件。

match parser.next() {
    ...
}

在文档结束或遇到错误时,解析器将记住最后的事件,并在之后的 next() 调用结果中始终返回该事件。

您还可以使用 xml::reader::ParserConfig 结构稍微调整解析过程。有关更多信息示例,请参阅其文档。

其他事项

未进行性能测试或测量。实现相当简单,未进行特定的优化。希望库足够快,能够处理常见大小的文档。

许可证

此库受 MIT 许可证许可。请随意在 GitHub 问题跟踪器上发布找到的问题:[http://github.com/netvl/rust-xml/issues](http://github.com/netvl/rust-xml/issues)。


版权所有 (C) Vladimir Matveev, 2014

无运行时依赖