Rust Serde:将 XML 直接反序列化为 Vec<T>

Jac*_*lli 6 xml serialization rust deserialization serde

我需要用来serde序列化一些 XML 数据。数据具有一种模式,其中复数形式的标签名称(例如 CATS、DOGS)将包含单数形式的标签子标签的多个实例(CAT、DOG),如下所示:

<pets>
  <cats>
    <cat>
      <name>
          cat 1
      </name>
    </cat>
    <cat>
      <name>
          cat 2
      </name>
    </cat>
  </cats>
  <dogs>
    <dog>
      <name>
          dog 1
      </name>
    </dog>
    <dog>
      <name>
          dog 2
      </name>
    </dog>
  </dogs>
</pets>
Run Code Online (Sandbox Code Playgroud)

现在,我可以用serdeand反序列化它serde-xml-rs

use serde::{Serialize, Deserialize};
use serde_xml_rs;

#[derive(Debug, Serialize, Deserialize)]
struct Pets {
    pub cats: Cats,
    pub dogs: Dogs,
}

#[derive(Debug, Serialize, Deserialize)]
struct Cats {
    pub cat: Vec<Cat>,
}

#[derive(Debug, Serialize, Deserialize)]
struct Dogs {
    pub dog: Vec<Dog>,
}

#[derive(Debug, Serialize, Deserialize)]
struct Cat {
    name: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct Dog {
    name: String,
}


fn main() {
    let s = xml_string_from_above;
    let pets: Pets = serde_xml_rs::from_str(s).unwrap();
    println!("{:#?}", pets);
}
Run Code Online (Sandbox Code Playgroud)

问题:我能使用一些黑客SERDE去除中间结构CatsDogs与简单地得到一个向量的多个实例?

#[derive(Debug, Serialize, Deserialize)]
struct SlimmedPets {
    pub cats: Vec<Cat>,
    pub dogs: Vec<Dog>,
}
Run Code Online (Sandbox Code Playgroud)

在序列化SlimmedPets结构时仍然获得相同的 XML ?

Cae*_*sar 0

如果您的目标是避免写下像这个问题这样的中间结构,我认为没有一个好的方法可以做到这一点。

\n

如果您的目标是从反序列化中获得与用于生成反序列化器的结构不同的结构,则可以使用serde(from = "\xe2\x80\xa6",into = "\xe2\x80\xa6") 属性

\n
#[derive(Debug, Serialize, Deserialize, Clone)]\n#[serde(from = "Pets", into = "Pets")]\nstruct SlimmedPets {\n    pub cats: Vec<Cat>,\n    pub dogs: Vec<Dog>,\n}\n\nimpl Into<Pets> for SlimmedPets {\n    fn into(self) -> Pets {\n        Pets {\n            cats: Cats { cat: self.cats },\n            dogs: Dogs { dog: self.dogs },\n        }\n    }\n}\n\nimpl From<Pets> for SlimmedPets {\n    fn from(from: Pets) -> Self {\n        SlimmedPets {\n            cats: from.cats.cat,\n            dogs: from.dogs.dog,\n        }\n    }\n}\n\nlet pets: SlimmedPets = serde_xml_rs::from_str(xml_string_from_above).unwrap();\n
Run Code Online (Sandbox Code Playgroud)\n