读取XML文件到结构中
问题描述:
我正在尝试编写一个将XML文件读入先前定义的Rust结构的程序。读取XML文件到结构中
事情是这样的:
<?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的新手,我很难搞清楚如何执行这个任务。
答
添加包装箱到你
Rust对自动生成(反)序列化代码有很大的支持。有传统rustc-serialize
这需要很少的设置。然后是serde
箱子,这是一个全新的(德)序列化框架,允许多种格式和详细的自定义配置,但需要更多的初始设置。
我将介绍如何使用serde
+ serde_xml_rs
将XML反序列化为Rust-structs。
添加包装箱到你Cargo.toml
我们可以手动执行反串行化代码,或者我们可以通过使用serde_derive
箱子自动生成它。
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde_xml_rs = "0.2.0"
添加注释到您的结构
SERDE需要了解你的结构。为了帮助它,而不是为项目中的每个结构生成代码,您需要注释所需的结构。 Debug
派生是因此我们可以轻松地使用println!
打印结构来检查是否一切正常。 Deserialize
界限是什么通知serde
生成代码。如果要将xml标记的内容作为文本处理,则需要将包含文本的字段“重命名”为$value
。 $value
的命名在创建serde_xml_rs
箱子时非常随意地完成,但永远不会与实际字段相冲突,因为字段名称不能包含$
标志。
#[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的字符串转换成对象
现在到了容易的部分。您在您的字符串上调用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);
}