将 XML 文件读入结构 [英] Read XML file into struct

查看:15
本文介绍了将 XML 文件读入结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个将 XML 文件读入之前定义的 Rust 结构的程序.

I am trying to write a program that reads an XML file into a previously defined Rust struct.

类似这样的:

<?xml version="1.0" encoding="UTF-8"?>
<note name="title">
  <body name="main_body">
    <layer content_type="something" count="99">
      <data id="13">
        Datacontent
      </data>
    </layer>
  </body>
</note>

进入这个:

struct Note {
    name: String,
    Body: Body 
}

struct Body {
    name: String,
    layers: Vec<Layer>,
}

struct Layer {
    content_type: String,
    count: u8,
    data: Vec<Data>,
}

struct Data {
    id: u8,
    // Datacontent?
}

我查看了 xml-rs,因为它目前似乎是最流行的 XML 库.作为 Rust 新手,我很难弄清楚如何执行这项任务.

I looked at xml-rs because it currently appears to be the most popular XML library. Being new to Rust, I have a hard time figuring out how to perform this task.

推荐答案

Rust 对自动生成(反)序列化代码有很好的支持.遗留的 rustc-serialize 需要很少的设置.然后是 serde crate,它是一个全新的(反)序列化框架,允许多种格式和详细的自定义配置,但需要更多的初始设置.

Rust has great support for automatically generating (de)serialization code. There's the legacy rustc-serialize which requires very little setup. Then there's the serde crate which is a completely new (de)serialization framework that allows many formats and detailed custom configurations, but requires a little more initial setup.

我将介绍如何使用 serde + serde_xml_rs 将 XML 反序列化为 Rust 结构.

I'm going to describe how to use serde + serde_xml_rs to deserialize the XML to the Rust-structs.

我们可以手动实现反序列化代码,也可以使用 serde_derive crate 自动生成它.

We could either implement the deserialization code manually, or we can generate it automatically by using the serde_derive crate.

[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde-xml-rs = "0.3.1"

为您的结构添加注释

Serde 需要了解您的结构.为了帮助它而不是为项目中的每个结构生成代码,您需要注释所需的结构.Debug 派生是为了让我们可以轻松地使用 println! 打印结构,以检查一切是否正常.Deserialize 绑定通知 serde 生成代码.如果要将 xml 标记的内容视为文本,则需要重命名";应包含 $value 文本的字段.$value 的命名在 serde_xml_rs crate 的创建中是非常随意的,但不能与实际的字段发生冲突,因为字段名不能包含 $ 符号.

Add annotations to your structs

Serde needs to know about your structs. To aid it and not generate code for every single struct in your project, you need to annotate the structs you want. The Debug derivation is so we can easily print the structs with println! to inspect whether everything worked. The Deserialize bound is what notifies serde to generate code. If you want to treat the contents of an xml tag as text, you need to "rename" the field that should contain the text to $value. The naming of $value was done very arbitrarily in the creation of the serde_xml_rs crate, but can never collide with an actual field, because field names can't contain $ signs.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_xml_rs;

#[derive(Deserialize, Debug)]
struct Note {
    name: String,
    body: Body,
}

#[derive(Deserialize, Debug)]
struct Body {
    name: String,
    #[serde(rename="layer")]
    layers: Vec<Layer>,
}

#[derive(Deserialize, Debug)]
struct Layer {
    content_type: String,
    count: u8,
    data: Vec<Data>,
}

#[derive(Deserialize, Debug)]
struct Data {
    id: u8,
    #[serde(rename="$value")]
    content: String,
}

将包含xml的String转成对象

现在是简单的部分.您在字符串上调用 serde_xml::from_str 并得到错误或 Node:

fn main() {
    let note: Note = serde_xml_rs::deserialize(r##"
<?xml version="1.0" encoding="UTF-8"?>
<note name="title">
  <body name="main_body">
    <layer content_type="something" count="99">
      <data id="13">
        Datacontent
      </data>
    </layer>
  </body>
</note>
    "##.as_bytes()).unwrap();
    println!("{:#?}", note);
}

这篇关于将 XML 文件读入结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆