Ответ 1
Rust прекрасно поддерживает автоматическую генерацию (де) кода сериализации. Там rustc-serialize
которая требует очень мало настроек. Тогда есть serde
crate, который является совершенно новой (де) платформой сериализации, которая допускает множество форматов и подробных пользовательских конфигураций, но требует немного более начальной настройки.
Я собираюсь описать, как использовать serde
+ serde_xml_rs
десериализации XML к ржавчине структур.
Добавьте ящики к вашему Cargo.toml
Мы можем либо реализовать код десериализации вручную, либо мы можем сгенерировать его автоматически с помощью ящика serde_derive
.
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde-xml-rs = "0.3.1"
Добавьте аннотации к своим структурам
Серде нужно знать о твоих структурах. Чтобы помочь этому, а не генерировать код для каждой отдельной структуры в вашем проекте, вам нужно аннотировать структуры, которые вы хотите. Debug
является производной, поэтому мы можем легко напечатать структуры с помощью println!
проверить, все ли работает. Deserialize
- это то, что уведомляет serde
для генерации кода. Если вы хотите трактовать содержимое тега xml как текст, вам необходимо "переименовать" поле, которое должно содержать текст, в $value
. При создании ящика serde_xml_rs
присвоено наименование $value
очень произвольно, но оно никогда не может столкнуться с фактическим полем, поскольку имена полей не могут содержать знаки $
.
#[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);
}