如何用serde_xml_rs解析含集合结构的XML并解决解析报错?
解决serde_xml_rs解析嵌套集合XML的问题
你的问题核心是没有显式指定集合元素的名称,导致serde_xml_rs无法正确识别<list>下的<item>节点。serde_xml_rs默认会尝试将Vec字段直接映射到父节点的子元素,但它不知道这些子元素的标签是<item>,反而误将<list>节点本身当作Item实例解析,因此找不到<something>字段报错。
你可以通过两种方式解决这个问题:
方法1:使用中间结构体包裹集合
通过一个中间结构体对应<list>节点,再在其中显式指定<item>节点对应的Vec字段:
use serde::Deserialize; const DATA_XML: &str = r###"<data> <name>test</name> <list> <item> <something>1</something> </item> <item> <something>2</something> </item> <item> <something>3</something> </item> </list> </data> "###; #[derive(Debug, Deserialize)] #[serde(rename = "data")] struct Data { name: String, list: List, } #[derive(Debug, Deserialize)] struct List { // 显式指定<item>节点对应这个Vec字段 #[serde(rename = "item")] items: Vec<Item>, } #[derive(Debug, Deserialize)] struct Item { something: String, } fn main() { let data: Data = serde_xml_rs::from_str(DATA_XML).unwrap(); println!("data = {:#?}", data); }
方法2:使用deserialize_with直接解析指定节点
利用serde_xml_rs提供的deserialize_nodes函数,直接从<list>节点中解析所有<item>子节点,同时给Item结构体指定对应的XML标签:
use serde::Deserialize; use serde_xml_rs::deserialize_nodes; const DATA_XML: &str = r###"<data> <name>test</name> <list> <item> <something>1</something> </item> <item> <something>2</something> </item> <item> <something>3</something> </item> </list> </data> "###; #[derive(Debug, Deserialize)] #[serde(rename = "data")] struct Data { name: String, // 从<list>节点中解析所有<item>子节点为Vec<Item> #[serde(deserialize_with = "deserialize_nodes::<Item>")] list: Vec<Item>, } #[derive(Debug, Deserialize)] // 显式指定Item对应的XML标签是<item> #[serde(rename = "item")] struct Item { something: String, } fn main() { let data: Data = serde_xml_rs::from_str(DATA_XML).unwrap(); println!("data = {:#?}", data); }
两种方式都能让serde_xml_rs正确识别XML中的集合结构,解决字段缺失的报错。
内容的提问来源于stack exchange,提问作者Petr Kozelka
相关产品推荐
相关产品推荐

