Rust实用技巧 | 如何在Rust中读取xml文件内容? | quick-xml

548 阅读3分钟

大家好,我是梦兽。一个 WEB 全栈开发和 Rust 爱好者。如果你对 Rust 非常感兴趣,可以关注梦兽编程公众号获取群,进入和梦兽一起交流。

我们可以使用 Rust 中的 crate quick-xml 来读取 XML 文件。

让我们将 quick-xml 添加到我们的依赖项中:

[dependencies]
quick-xml = "0.36.1"

使用quick-xml也是非常简单的:

use quick_xml::{events::Event, Reader};

fn main() {
  let xml = r#"<person id="1"><name>Jim</name></person>"#;
  let mut reader = Reader::from_str(&xml);

  let mut buffer = Vec::new();

  loop {
      match reader.read_event_into(&mut buffer) {
          Err(e) => panic!("{:?}" , e),
          // 推出解析
          Ok(Event::Eof) => break,
          Ok(Event::Start(e)) => {
            // 解析标签我们可以e.name() 进行匹配,并使用e.attributes()获取所有属性
            match e.name().as_ref() {
                b"person" => println!("{:?}", e.attributes().map(|a| a).collect::<Vec<_>>()),
                b"name" => println!("{:?}", e.attributes().map(|a| a).collect::<Vec<_>>()),
                _ => ()
            }
          },
           // 如果事件是文本内容(例如 "Jim")
          Ok(Event::Text(text)) => println!("{:?}"String::from_utf8(text.to_vec()).unwrap()),
          _ => ()
      }
  }

  println!("{}"String::from_utf8(buffer).unwrap());
}

存在什么问题?

你会发现,在我们解析XML的过程,会发现处理业务代码做映射时,用match进行解析会存在一些奇怪的操作比如:

use quick_xml::Reader;
use quick_xml::events::Event;

fn main() {
    let xml = r#"<root><tag>内容</tag></root>"#;
    let mut reader = Reader::from_str(xml);
    reader.trim_text(true);

    let mut buf = Vec::new();
    // 我们需要一个变量来标识你当前的位置Tag位置
    let mut in_tag = false;

    loop {
        match reader.read_event(&mut buf) {
            // 如果是我们的tag标签
            Ok(Event::Start(ref e)) if e.name() == b"tag" => in_tag = true,
            Ok(Event::End(ref e)) if e.name() == b"tag" => {
                // 别问了要释放tag标识哦
                in_tag = false;
            }
            Ok(Event::Text(e)) if in_tag => {
                // 写入内容
                println!("内容: {:?}", e.unescape_and_decode(&reader).unwrap());
            }
            Ok(Event::Eof) => break,
            Err(e) => panic!("Error: {:?}", e),
            _ => (),
        }
        buf.clear();
    }
}
> 也有可能是小编目前对这个lib不熟,如果有更好的写法。可以评论区回复。

想偷懒使用serde的解决方案

在Java圈子,很多解决方案由Spring团队提供并解决。在Rust圈子同样也存在这么一个组织serde。 你可以使用 quick-xml 和 serde-xml-rs 来解析 XML。首先,定义一个结构体来表示你的 XML 结构,并使用 serde 来实现序列化和反序列化。例如:

use quick_xml::de::from_str;
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct MyStruct {
    #[serde(rename = "tag")]
    content: String,
}

fn main() {
    let xml = r#"<root><tag>内容</tag></root>"#;
    let result: MyStruct = from_str(xml).unwrap();
    println!("{:?}", result);
}

在本文中,我们探讨了如何使用Rust中的quick-xml库来读取和解析XML文件内容。我们首先介绍了基本的解析流程,包括如何处理标签和文本内容,并讨论了一些可能遇到的挑战。随后,我们展示了如何利用serde库简化解析过程,通过定义结构体来高效地反序列化XML数据。这种方法不仅提高了代码的可读性,还减少了出错的可能性。感谢您的阅读,希望这篇文章对您在Rust开发中处理XML有所帮助。如果您有任何建议或更好的实现方式,请随时分享!

注意

感谢阅读!感谢您的时间,并希望您觉得这篇文章有价值。在您的下一个 JavaScript 项目中尝试使用柯里化,并在下面的评论中告诉我它如何改善了您的编码体验!

创建和维护这个博客以及相关的库带来了十分庞大的工作量,即便我十分热爱它们,仍然需要你们的支持。或者转发文章。通过赞助我,可以让我有能投入更多时间与精力在创造新内容,开发新功能上。赞助我最好的办法是微信公众号看看广告。

本文使用 markdown.com.cn 排版