我正在尝试编写一个将XML文件读入先前定义的Rust结构的程序。
这样的事情:
<?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的新手,我很难搞清楚如何执行这项任务。
答案 0 :(得分:22)
Rust非常支持自动生成(de)序列化代码。遗留rustc-serialize
需要很少的设置。然后是serde
crate,它是一个全新的(de)序列化框架,允许许多格式和详细的自定义配置,但需要更多的初始设置。
我将介绍如何使用serde
+ serde_xml_rs
将XML反序列化为Rust-structs。
Cargo.toml
我们可以手动实现反序列化代码,也可以使用serde_derive
包自动生成它。
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde-xml-rs = "0.3.1"
Serde需要了解你的结构。为了帮助它而不为项目中的每个结构生成代码,您需要注释所需的结构。 Debug
推导是我们可以使用println!
轻松打印结构以检查是否一切正常。 Deserialize
绑定是通知serde
生成代码的内容。如果要将xml标记的内容视为文本,则需要重命名&#34;应包含$value
文本的字段。 $value
的命名在创建serde_xml_rs
包中时非常随意,但永远不会与实际字段发生冲突,因为字段名称不能包含$
个符号。< / p>
#[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,
}
现在很简单。您在字符串上调用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);
}