Rust có hỗ trợ tuyệt vời để tự động tạo (de) mã tuần tự hóa. Có di sản rustc-serialize
yêu cầu thiết lập rất ít. Sau đó, có thùng serde
là một khung công tác tuần tự hoàn toàn mới (de) cho phép nhiều định dạng và cấu hình tùy chỉnh chi tiết, nhưng yêu cầu thiết lập ban đầu hơn một chút.
Tôi sẽ mô tả cách sử dụng serde
+ serde_xml_rs
để deserialize XML thành cấu trúc Rust.
Thêm thùng để bạn Cargo.toml
Chúng tôi có thể thực hiện một trong hai mã deserialization bằng tay, hoặc chúng ta có thể tạo ra nó tự động bằng cách sử dụng các serde_derive
thùng.
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde_xml_rs = "0.2.0"
Thêm chú thích để struct của bạn
Serde cần biết về cấu trúc của bạn. Để hỗ trợ nó và không tạo mã cho mỗi cấu trúc đơn lẻ trong dự án của bạn, bạn cần chú thích các cấu trúc mà bạn muốn. Các dẫn xuất Debug
là vì vậy chúng tôi có thể dễ dàng in các cấu trúc với println!
để kiểm tra xem mọi thứ có hoạt động hay không. Các ràng buộc Deserialize
là những gì thông báo serde
để tạo mã. Nếu bạn muốn xử lý nội dung của thẻ xml dưới dạng văn bản, bạn cần phải "đổi tên" trường sẽ chứa văn bản thành $value
. Việc đặt tên của $value
được thực hiện rất tùy ý trong việc tạo ra các thùng serde_xml_rs
, nhưng không bao giờ có thể va chạm với một trường thực tế, bởi vì tên trường không thể chứa các dấu hiệu $
.
#[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,
}
Rẽ một String chứa xml thành một đối tượng
Bây giờ đến phần dễ dàng. Bạn gọi số serde_xml::from_str
trên chuỗi của mình và bạn nhận được lỗi hoặc giá trị loại 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);
}