xml - 无法使用 serde-xml-rs 解析带有可选元素的 XML

标签 xml rust serde

我有一个带有 serde 注释的结构树,它成功地解析了示例 XML,包括这个片段:

<bmsg>
    <cmsg>
         <!-- ... -->
    <cmsg>
<bmsg>

现在我正在测试一个大型样本 XML 文件,以下结构失败,因为有时 <cmsg>..</cmsg>不见了。我正在反序列化这个使用:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename="bmsg")]
    messages: B,                 // <====
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename="cmsg")]
    list: Vec<C>,
}

这导致了第二个结构的错误:

panicked at 'called `Result::unwrap()` on an `Err` value: missing field `cmsg`

我将第一个结构更改为 Vec<>所以它可以处理一个可选元素:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename="bmsg")]
    messages: Vec<B>,            // <====
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename="cmsg")]
    list: Vec<C>,
}

但是 serde 继续给出同样的错误。我试过 Option<>也,但没有得到任何地方。

最让我困惑的是我使用 Vec<>到处都是,从来没有遇到过这个问题。

最佳答案

它会出现 Option<T>表示该项目确实存在,只是没有内容。

The documentation seems to suggest using default属性,告诉反序列化器使用 Default trait 的实现对于类型如果找不到

考虑到这一点,也许这对你有用:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename = "bmsg")]
    messages: B,
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename = "cmsg", default)] // <----- use default to call `Default::default()` against this vector
    list: Vec<C>,
}

你可以找到the code I used to check this in the Playground .它不会在 Playground 中运行,但会产生您在本地运行的预期结果。

关于xml - 无法使用 serde-xml-rs 解析带有可选元素的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46585332/

相关文章:

xml - MarkLogic:XQuery 从 XML 文档中获取值?

java - 为 Google 的 Android 滑动选项卡着色

rust - 为什么在函数返回时从 `HashMap::get`借用还没有结束?

multithreading - 如何创建可在 Rust 多线程服务器中使用的结构?

generics - Rust 和 serde 使用泛型反序列化

c# - 加扰 XML 中的文本元素

string - 生命周期如何作用于常量字符串/字符串文字?

enums - 有没有办法在 Rust 中使用 "flatten"枚举进行(反)序列化?

rust - 从Vec <u32>进行序列化和反序列化

java - 在 JAXB API 中向 xml 元素添加属性