首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多种可能类型解析XML标记[Rust,serde,serde-xml-rs]

使用多种可能类型解析XML标记[Rust,serde,serde-xml-rs]
EN

Stack Overflow用户
提问于 2021-10-04 11:55:52
回答 1查看 97关注 0票数 1

我想解析一个可能包含不同数据类型的XML元素。

下面是我能想到的最简单的例子:

代码语言:javascript
复制
use serde_derive::{Deserialize, Serialize};
use serde_xml_rs::{from_str};

const XML: &str = r#"
<element>
    foo
</element>
"#;
const XML2: &str = r#"
<element>
    123
</element>
"#;

#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Element {
    #[serde(rename="element")]
    Text(String),
    #[serde(rename="element")]
    Number(i32),
}

fn main() {
    let el: Element = from_str(&XML).unwrap();
    println!("{:?}", &el);
    println!("\n\n\n\n");
    let el2: Element = from_str(&XML2).unwrap();
    println!("{:?}", &el2);
}

当前代码将这两个元素分别解析为文本(String),而不是文本(String)和数字(I32)。

如果我颠倒顺序,程序就会崩溃,因为"foo“不能被解析为整数。

代码语言:javascript
复制
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Element {
    #[serde(rename="element")]
    Number(i32),
    #[serde(rename="element")]
    Text(String),
}

我如何正确地实现我的程序?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-04 18:42:15

如果我没理解错的话,只要值可以被解析为i32,你就需要Number,否则就需要Text。您可以使用FromStr特征实现这一点。

代码语言:javascript
复制
#[derive(Serialize, serde_with::DeserializeFromStr, Debug, PartialEq)]
enum Element {
    #[serde(rename="element")]
    Text(String),
    #[serde(rename="element")]
    Number(i32),
}

impl std::str::FromStr for Element {
    type Err = std::convert::Infallible;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if let Ok(i) = s.parse::<i32>() {
            Ok(Element::Number(i))
        } else {
            Ok(Element::Text(s.to_string()))
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69435590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档