2017-10-05 4 views
3

Ich habe einen Baum von serde-kommentierte structs und es gelingt in der Probe des Parsen von XML, einschließlich diesem Fragment:fehlgeschlagen mit serde-xml-rs XML mit einem optionalen Elemente analysieren

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

Jetzt bin ich Prüfung mit einer großen Beispiel-XML-Datei und die folgenden Strukturen fehlschlagen, weil manchmal <cmsg>..</cmsg> fehlt. Ich war Deserialisieren dies mit:

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

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

, die in einem Fehler in der zweiten Struktur ergaben:

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

ich die erste Struktur geändert hat einen Vec<> so kann es mit einem optionalen Elemente befassen:

#[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>, 
} 

Aber Serde gibt weiterhin den gleichen Fehler. Ich habe auch versucht Option<>, aber kam nirgendwo hin.

Was mich am meisten verwirrt ist, dass ich überall Vec<> benutze und nie in dieses Problem lief.

Antwort

4

Es scheint Option<T> bedeutet, dass das Element existiert, ist es nur inhaltsleer.

The documentation seems to suggest using das default Attribut, das Deserializer zu sagen, die Umsetzung der Default trait für den Typen , wenn es nicht gefunden werden kann zu verwenden.

Mit dem im Verstand, vielleicht wäre dies für Sie arbeiten:

#[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>, 
} 

Sie the code I used to check this in the Playground finden. Es wird nicht auf dem Spielplatz ausgeführt, aber es produziert Ihre erwarteten Ergebnisse lokal ausgeführt.

+2

Dies ist eine korrekte und sehr gut ausgearbeitete Antwort. Hinweis Ich habe versucht, # [serde (default)], aber nur auf der ersten struct:/Vielen Dank! – user103185