Rust非常支持自动生成(反)序列化代码.legacy rustc-serialize
只需要很少的设置.还有serde
crate ,这是一个全新的(反)序列化框架,允许多种格式和详细的自定义配置,但需要更多的初始设置.
我将描述如何使用serde
+serde_xml_rs
将XML反序列化为Rust struct .
Add the crates to your Cargo.toml
我们可以手动实现反序列化代码,也可以使用serde_derive
crate 自动生成反序列化代码.
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde-xml-rs = "0.3.1"
Add annotations to your structs
Serde需要了解你的 struct .为了帮助它,而不是为项目中的每个 struct 生成代码,您需要对所需的 struct 进行注释.Debug
派生是为了方便我们用println!
打印 struct ,以判断是否一切正常.Deserialize
边界通知serde
生成代码.如果希望将xml标记的内容视为文本,则需要将应该包含文本的字段"重命名"为$value
.$value
的命名在serde_xml_rs
crate 的创建过程中非常随意,但不能与实际字段冲突,因为字段名称不能包含$
个符号.
#[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,
}
Turn a String containing xml into an object
现在是最简单的部分.在字符串上调用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);
}