2017-10-05 42 views
3

我有SERDE標註結構的樹,它在解析XML示例,其中包括該片段成功:失敗與SERDE-XML-RS的可選元素解析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<>,從未遇到過這個問題。

回答

4

這樣看來Option<T>意味着該項目確實存在,它僅僅是空洞的內容。

The documentation seems to suggest usingdefault屬性,告訴解串器使用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中運行,但會產生您在本地運行的預期結果。

+2

這是一個正確和很好闡述的答案。注意我試過#[serde(默認)],但只在第一個結構上:/謝謝! – user103185