You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

serde能否反序列化格式为扁平键值对的XML数据?

解决方案

你遇到的这种<key>和值节点交替排列的扁平XML结构,serde-xml-rs没有内置的serde属性可以直接一步映射到你定义的Data结构体,可通过以下两种方式实现需求:

  • 方案一:中间层转换(实现成本最低,推荐)
    先解析为你目前已经实现的元组Vec中间结构,再手动映射为目标结构体:

    #[derive(Deserialize)]
    enum Node {
      #[serde(rename = "int")]
      Int(u32),
      #[serde(rename = "string")]
      String(String),
    }
    
    #[derive(Deserialize)]
    struct DataTemp {
      #[serde(rename = "$value")]
      entries: Vec<(String, Node)>,
    }
    
    struct Data {
      version: Node,
      name: Node,
    }
    
    // 解析转换逻辑
    let xml_str = r#"
    <data>
       <key>version</key>
       <int>4</int>
       <key>name</key>
       <string>John</string>
    </data>
    "#;
    let temp: DataTemp = serde_xml_rs::from_str(xml_str)?;
    let mut entries_iter = temp.entries.into_iter();
    let data = Data {
        version: entries_iter.find(|(k, _)| k == "version").unwrap().1,
        name: entries_iter.find(|(k, _)| k == "name").unwrap().1,
    };
    
  • 方案二:自定义Data的反序列化逻辑(可直接一步解析)
    为Data手动实现Deserialize trait,主动处理交替的key-value结构:

    use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
    use std::fmt;
    
    impl<'de> Deserialize<'de> for Data {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            struct DataVisitor;
    
            impl<'de> Visitor<'de> for DataVisitor {
                type Value = Data;
    
                fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    f.write_str("alternating key and value nodes")
                }
    
                fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
                where
                    A: MapAccess<'de>,
                {
                    let mut version = None;
                    let mut name = None;
    
                    while let Some(key) = map.next_key::<String>()? {
                        match key.as_str() {
                            "version" => version = Some(map.next_value()?),
                            "name" => name = Some(map.next_value()?),
                            _ => { let _: Node = map.next_value()?; }
                        }
                    }
    
                    Ok(Data {
                        version: version.ok_or_else(|| serde::de::Error::missing_field("version"))?,
                        name: name.ok_or_else(|| serde::de::Error::missing_field("name"))?,
                    })
                }
            }
    
            deserializer.deserialize_map(DataVisitor)
        }
    }
    
    // 直接解析即可得到Data实例
    let data: Data = serde_xml_rs::from_str(xml_str)?;
    

内容的提问来源于stack exchange,提问作者Vigdail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:48:05