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

时间:2017-10-05 12:11:55

标签: xml rust serde

我有一个带有serde-annotated结构的树,它成功解析了样本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>,
}

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

最令我困惑的是,我在整个地方使用Vec<>并且从未遇到过这个问题。

1 个答案:

答案 0 :(得分:6)

看起来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中运行,但会产生在本地运行的预期结果。