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

use*_*185 5 xml rust serde

我有一个serde-annotated结构树,它成功解析了示例XML,包括这个片段:

<bmsg>
    <cmsg>
         <!-- ... -->
    <cmsg>
<bmsg>
Run Code Online (Sandbox Code Playgroud)

现在我正在使用大型示例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>,
}
Run Code Online (Sandbox Code Playgroud)

这导致第二个结构中出错:

panicked at 'called `Result::unwrap()` on an `Err` value: missing field `cmsg`
Run Code Online (Sandbox Code Playgroud)

我改变了第一个结构,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>,
}
Run Code Online (Sandbox Code Playgroud)

但是,塞尔德继续给出同样的错误.我也试过Option<>,但没有到达任何地方.

最令我困惑的是,我Vec<>到处都使用,从不遇到这个问题.

Sim*_*ead 6

这似乎Option<T>意味着该项目确实存在,它只是没有内容.

该文件似乎使用建议default属性,告诉解串器使用的执行Default特征的类型,如果它不能找到.

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

#[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>,
}
Run Code Online (Sandbox Code Playgroud)

您可以在Playground中找到我用来检查的代码.它不会在Playground中运行,但会产生在本地运行的预期结果.

  • 这是一个正确且非常详细的答案.注意我试过#[serde(默认)],但只在第一个结构上:/谢谢! (2认同)