2010-10-16 13 views
9

मैं अपनी अगली परियोजनाओं में उपयोग करने के लिए एक सामान्य डेटा संरचना प्रदान करने के लिए दस्तावेज़ ऑब्जेक्ट मॉडल लाइब्रेरी का एक बहुत ही सरल कार्यान्वयन लिखने की कोशिश कर रहा हूं। बस चीजों को सरल रखने के लिए मैंने केवल तीन मुख्य वर्गों को परिभाषित किया: node, element और attribute। एक नोड को इसके नाम (जैसे सभी एचटीएमएल टैग) द्वारा परिभाषित किया जाता है और मूल रूप से एक तत्व के लिए एक कंटेनर होता है जो टेक्स्ट और सब-नोड्स (std::vector<node> में संग्रहीत) दोनों हो सकता है।सी ++ में एक सामान्य डोम डेटा संरचना को कैसे कार्यान्वित करें?

मैं सिर्फ एक संपूर्ण वृक्ष संरचना को परिभाषित करने का तरीका नहीं समझ सकता।

मुझे वर्गीकृत वर्ग के लिए टेम्पलेटीकृत इंटरफेस की आवश्यकता है। उपयोग के

उदाहरण:

element<string> txt1("Some text"); 

element< element<string> > div1("div", txt1); 

मैं एक्सएमएल के पूर्ण समर्थन के साथ एक पूर्ण डोम अमूर्त स्तर बनाने के लिए नहीं करना चाहती। मुझे सिर्फ डीओएम जैसी शैली में जानकारी व्यवस्थित करने के लिए विचारों की आवश्यकता है। कोई पार्सिंग की आवश्यकता नहीं है।

अग्रिम धन्यवाद!

+0

+1, अब मैं प्रश्न को बेहतर समझता हूं। मैंने सोचा था कि आप एक एक्सएमएल लाइब्रेरी को कार्यान्वित करने की कोशिश कर रहे थे :) –

उत्तर

1
इसके बजाय दृढ़ता से कितने माता-पिता यह है, एक वृक्ष संरचना के रूप में अपने कोड का आयोजन के आधार पर प्रत्येक नोड टाइप करने के लिए कोशिश कर के

:

class Element 
{ 
public: 
    std::string Name; 
    std::map<std::string, std::string, std::less<std::string> > Attributes; 
    std::list<Element> Children; 
}; 

आपकी सार्वजनिक इंटरफ़ेस शायद इस से अलग दिखेगा। मैं बस सामान्य प्रकार के लेआउट दिखाने की कोशिश कर रहा हूं।

आपको वास्तव में नोड या विशेषता सुविधाओं की आवश्यकता नहीं है, जब तक कि आपको तत्वों के साथ संग्रह में उन्हें पुन: सक्रिय करने की आवश्यकता न हो। यह एक्सएमएल डोम पुस्तकालयों के लिए एक उपयोगी विशेषता है, लेकिन यदि आप केवल डेटा संरचना बनाने की कोशिश कर रहे हैं, तो आपको पत्र में डीओएम डिज़ाइन का पालन करने की आवश्यकता नहीं है।

#include<map> 
#include<string> 
#include<iostream> 

class PropertyBag; 
typedef std::map<std::string, PropertyBag> PropertyMap; 

class PropertyBag : public PropertyMap 
{ 
public: 
    PropertyBag(const std::string& value) 
    : value(value) 
    { 
    } 

    PropertyBag& operator=(const std::string& value) 
    { 
    this->value = value; 
    return *this; 
    } 

    operator std::string&() { return value; } 

private: 
    std::string value; 

    friend PropertyMap::mapped_type& PropertyMap::operator[](const PropertyMap::key_type&); 
    PropertyBag() { } 
}; 

void SomeFunction(const std::string& value) 
{ 
    std::cout << value << "\n"; 
} 

int main(int argc, char* argv[]) 
{ 
    PropertyBag config("configuration root"); 
    config["child1"] = "value1"; 
    config["child1"]["subchild1"] = "value2"; 

    SomeFunction(config["child1"]); 
    SomeFunction(config["child1"]["subchild1"]); 
    return 0; 
} 

बस वाक्य रचना के बारे में बात, आप भी operator() अधिक भार के साथ मुश्किल प्राप्त करने की कोशिश कर सकते हैं:

वास्तव में, यदि आप सिर्फ एक सामान्य डेटा संरचना के लिए जा रहे हैं, तो आप सिर्फ एक संपत्ति बैग चाहते हो सकता है , और/या चेनिंग तरीके:

PropertyBag& SomeMethod(const std::string& someParam) 
{ 
    // do something here... 
    return *this; 
} 

PropertyBag& operator()(const std::string& p1, const std::string& p2) 
{ 
    // ... 
    return *this; 
} 

// ... 

Configuration config1("root") 
    .SomeMethod("p1") 
    .SomeMethod("p2"); 
Configuration config2("root") 
    ("Something", "blah") 
    ("sizzle", "V2"); 

मैं कम पाठ/कोड दोहराव, बेहतर कल्पना। जितना अधिक आप अपने कोड को JSON या YAML जैसे वाक्यविन्यास के लिए प्राप्त कर सकते हैं, उतना ही बेहतर।

एक बार सी ++ 0x बाहर निकलने के बाद, आपके पास बहुत आसान विकल्प उपलब्ध हो सकते हैं।आप अपनी डेटा संरचना पर उपयोग करने के लिए एक आसान प्रारंभिक वाक्यविन्यास के लिए boost::assign library पर भी देख सकते हैं।

आप एक डेटाटाइप के लिए boost::any library पर भी देख सकते हैं, जिसे आप स्ट्रिंग्स के बजाय मूल्य के रूप में उपयोग कर सकते हैं (किसी भी मूल्य को डालने के प्रकार-सुरक्षित विधि का समर्थन करता है, जब तक आप इसे उसी प्रकार के रूप में निकालें)।

+0

@Merlyn: सूची में भयानक रनटाइम प्रदर्शन है, क्या आप वाकई वेक्टर नहीं चाहते हैं? –

+1

@Matthieu: एक सूची बेहतर संचालन का प्रतिनिधित्व करती है जो आप इस तरह की संरचना पर करेंगे। आप आकार के साथ शुरू करने के बारे में नहीं जानते हैं, और आप कभी भी बच्चों पर सूचकांक आधारित पहुंच नहीं करेंगे। इस परिदृश्य में, एक सूची निर्माण के लिए बेहतर प्रदर्शन कर सकती है, और ट्रैवर्सल के लिए जितनी जल्दी हो सके। लेकिन वास्तविक जीवन में, इस प्रकार का पेर्फ शायद ही कभी एक बाधा बनने जा रहा है, और यदि ऐसा है, तो आप सामान्य डेटा संरचना के बजाय ऐप के उस हिस्से के लिए एक कस्टम स्टोरेज समाधान के साथ आएंगे। –

+1

@Merlyn: एक कस्टम स्टोरेज समाधान के लिए जा रहा एक अंतिम उपाय समाधान है, विशेषज्ञों के लिए आरक्षित। सूची पसंद के लिए, मैं दृढ़ता से असहमत हूं। एक कंटेनर की पहली पसंद या तो 'वेक्टर' या 'डेक' होना चाहिए, क्योंकि वे सरल हैं। केवल तभी यदि आपके पास विशिष्ट आवश्यकताओं को बदलना चाहिए: यूनिकिटी के लिए 'unordered_set', ऑर्डर करने के लिए' सेट ', विशिष्ट पहुंच के लिए' स्टैक '/ 'कतार' आदि ... सामान्य रूप से 'सूची' का उपयोग करने का एकमात्र लाभ, इटरेटर अमान्यता गारंटी है। –

0

यदि आप मेरे पिछले उत्तरों को देखते हैं, तो आप देखेंगे कि मैं टेम्पलेट्स का समर्थक हूं, लेकिन यदि आपके पास कोई अन्य आवश्यकता नहीं है, तो वे केवल रास्ते में आ जाएंगे। पार्सर्स को निपटने के लिए कई अलग-अलग प्रकार पसंद नहीं हैं। (हालांकि आप कहते हैं कि आपको एक पार्सर की आवश्यकता नहीं है - हू?)

एक्सएमएल और डीओएम का बिंदु किसी भी आंतरिक संरचना से और अनुवाद करना आसान बनाना है। न केवल आपको एक XML नोड टेम्पलेट को परिभाषित करने की आवश्यकता नहीं है, आपको किसी भी कस्टम डेटा संरचना की आवश्यकता नहीं होनी चाहिए। कोई भी संरचना पहले से ही डोम जैसी शैली में है। डीएजी परेशान हैं, क्योंकि वे थोड़े पेड़ और थोड़े-ग्राफ हैं, लेकिन आप संकेत नहीं देते कि आप उस तरह के रोडब्लॉक को मार रहे हैं।

आप कहते हैं (हटाए गए उत्तर पर टिप्पणी में) कि आप मौजूदा लाइब्रेरी का उपयोग नहीं करना चाहते हैं। क्यूं कर? आप वास्तव में क्या करने की कोशिश कर रहे हैं?

+0

"हालांकि आप कहते हैं कि आपको एक पार्सर की आवश्यकता नहीं है - हुह?" हाँ! यह सही है, मुझे एक पार्सर की ज़रूरत नहीं है! मेरा पार्सिंग मैथोड एक बहुत ही निहित प्रक्रिया है। जब मैंने इसे किया है तो मैं आपको कुछ उदाहरण दिखा सकता हूं। मैं जो कर रहा हूं वह HTML के लिए एक टेम्पलेट इंजन है - इसलिए मैं डोम वृक्ष मैनिपुलेशन में उपयोग करने के लिए एक सार HTML डेटा प्रतिनिधित्व करना चाहता हूं। – Rizo

+0

@Rizo: उस स्थिति में, आप एक पार्सर लिख रहे हैं और आप अपना स्वयं का HTML (एक्सएमएल नहीं) लाइब्रेरी बना रहे हैं। और जैसे मैंने कहा, जब तक टेम्पलेट का उपयोग करने का कोई कारण नहीं है, वे बस रास्ते में आ जाएंगे। – Potatoswatter

+0

मैंने सोचा कि एक्सएमएल वाक्य रचनात्मक रूप से और तार्किक रूप से एचटीएमएल के बराबर था (है ना?)। – Rizo

संबंधित मुद्दे