如何在Rust中用serde-xml-rs反序列化XML中的字符串布尔值
解决serde-xml-rs解析字符串布尔值为bool类型的错误
在使用serde-xml-rs解析XML响应时,若要将XML中"TRUE"/"FALSE"形式的字符串布尔值转换为自定义结构体的bool字段,直接套用JSON场景的借用&str写法会触发错误:invalid type: string "TRUE", expected a borrowed string,这源于serde-xml-rs对借用字符串的支持存在限制。
解决方案
将反序列化函数中原本的&str替换为拥有所有权的String类型,即可避开借用字符串的兼容性问题。
修改后的完整代码
Cargo.toml
[package] name = "test_range_2" version = "0.1.0" edition = "2021" [dependencies] serde = { version = "1.0.147", features = ["derive"] } serde-xml-rs = "0.6.0"
main.rs
use serde::Deserialize; fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error> where D: serde::de::Deserializer<'de>, { // 将&str改为String,避免借用字符串的兼容问题 let s: String = serde::de::Deserialize::deserialize(deserializer)?; match s.as_str() { "TRUE" => Ok(true), "FALSE" => Ok(false), _ => Err(serde::de::Error::unknown_variant(&s, &["TRUE", "FALSE"])), } } #[allow(dead_code)] #[derive(Debug, Deserialize)] struct Custom { #[serde(deserialize_with = "deserialize_bool")] tag1: bool, #[serde(deserialize_with = "deserialize_bool")] tag2: bool, } fn main() { let xml_raw = r#" <?xml version="1.0"?> <Custom> <tag1>TRUE</tag1> <tag2>FALSE</tag2> </Custom> "#; let custom = serde_xml_rs::from_str::<Custom>(xml_raw) .expect("unable to deserialize xml into Custom struct"); println!("{:#?}", custom); }
运行结果
Custom { tag1: true, tag2: false, }
原理说明
serde-xml-rs处理文本节点时,内部实现更偏向生成拥有所有权的字符串,而非借用原输入的字符串。尝试反序列化为&str时,会因无法提供符合要求的生命周期借用而报错。改用String后,反序列化器可正常生成所有权字符串,后续通过as_str()转换为切片即可完成匹配判断。
内容的提问来源于stack exchange,提问作者Pavel Skipenes
相关产品推荐
相关产品推荐

