2016-06-22 9 views
9

में एक्सएमएल फ़ाइल पढ़ें मैं एक प्रोग्राम लिखने की कोशिश कर रहा हूं जो पहले से परिभाषित जंग संरचना में एक एक्सएमएल फ़ाइल पढ़ता है।संरचना

कुछ इस तरह:

<?xml version="1.0" encoding="UTF-8"?> 
<note name="title"> 
    <body name="main_body"> 
    <layer content_type="something" count="99"> 
     <data id="13"> 
     Datacontent 
     </data> 
    </layer> 
    </body> 
</note> 
इस में

:

struct Note { 
    name: String, 
    Body: Body 
} 

struct Body { 
    name: String, 
    layers: Vec<Layer>, 
} 

struct Layer { 
    content_type: String, 
    count: u8, 
    data: Vec<Data>, 
} 

struct Data { 
    id: u8, 
    // Datacontent? 
} 

मैं xml-rs को देखा है क्योंकि यह वर्तमान में सबसे लोकप्रिय एक्सएमएल पुस्तकालय प्रतीत होता है। जंग के लिए नया होने के नाते, मुझे यह पता लगाना मुश्किल है कि इस कार्य को कैसे किया जाए।

उत्तर

14

जंग को स्वचालित रूप से उत्पन्न (डी) क्रमबद्धता कोड के लिए बहुत अच्छा समर्थन है। विरासत rustc-serialize है जिसके लिए बहुत कम सेटअप की आवश्यकता है। फिर serde क्रेट है जो एक पूरी तरह से नया (डी) धारावाहिक ढांचा है जो कई प्रारूपों और विस्तृत कस्टम कॉन्फ़िगरेशन की अनुमति देता है, लेकिन थोड़ा और प्रारंभिक सेटअप की आवश्यकता होती है।

मैं वर्णन करने जा रहा हूं कि serde + serde_xml_rs का उपयोग एक्सएमएल को जंग-structs में deserialize करने के लिए कैसे करें।

अपने Cargo.toml

को क्रेट जोड़े हम या तो अक्रमांकन कोड मैन्युअल रूप से लागू कर सकता है, या हम serde_derive टोकरा का उपयोग करके स्वचालित रूप से इसे उत्पन्न कर सकते हैं।

[dependencies] 
serde_derive = "1.0" 
serde = "1.0" 
serde_xml_rs = "0.2.0" 

अपने structs

Serde अपने structs के बारे में पता करने की जरूरत है में टिप्पणियां जोड़ें। इसे आपकी सहायता करने के लिए और अपनी परियोजना में प्रत्येक एकल संरचना के लिए कोड उत्पन्न नहीं करने के लिए, आपको इच्छित structs को एनोटेट करने की आवश्यकता है। Debug व्युत्पन्न इसलिए है कि हम सबकुछ काम करते हैं या नहीं, यह जांचने के लिए हम println! के साथ आसानी से structs प्रिंट कर सकते हैं। कोड उत्पन्न करने के लिए Deserialize बाध्य है जो serde को सूचित करता है। यदि आप टेक्स्ट के रूप में किसी XML टैग की सामग्री का इलाज करना चाहते हैं, तो आपको उस फ़ील्ड को "नाम बदलें" करना होगा जिसमें टेक्स्ट को $value पर रखना चाहिए। $value का नाम serde_xml_rs क्रेट के निर्माण में बहुत ही मनमाने ढंग से किया गया था, लेकिन कभी भी वास्तविक क्षेत्र से टकरा नहीं सकता है, क्योंकि फ़ील्ड नामों में $ संकेत नहीं हो सकते हैं।

#[macro_use] 
extern crate serde_derive; 

extern crate serde; 
extern crate serde_xml_rs; 

#[derive(Deserialize, Debug)] 
struct Note { 
    name: String, 
    body: Body, 
} 

#[derive(Deserialize, Debug)] 
struct Body { 
    name: String, 
    #[serde(rename="layer")] 
    layers: Vec<Layer>, 
} 

#[derive(Deserialize, Debug)] 
struct Layer { 
    content_type: String, 
    count: u8, 
    data: Vec<Data>, 
} 

#[derive(Deserialize, Debug)] 
struct Data { 
    id: u8, 
    #[serde(rename="$value")] 
    content: String, 
} 

एक वस्तु

अब आसान हिस्सा आता है में एक स्ट्रिंग एक्सएमएल युक्त कर दें। आप अपनी स्ट्रिंग पर serde_xml::from_str पर कॉल करते हैं और आपको या तो Node:

fn main() { 
    let note: Note = serde_xml_rs::deserialize(r##" 
<?xml version="1.0" encoding="UTF-8"?> 
<note name="title"> 
    <body name="main_body"> 
    <layer content_type="something" count="99"> 
     <data id="13"> 
     Datacontent 
     </data> 
    </layer> 
    </body> 
</note> 
    "##.as_bytes()).unwrap(); 
    println!("{:#?}", note); 
} 
पर कोई त्रुटि या मान मिलता है