C ++ में मुझे XML पार्सर का क्या उपयोग करना चाहिए? [बन्द है]


344

मेरे पास XML दस्तावेज़ हैं जिन्हें मुझे पार्स करने की आवश्यकता है और / या मुझे XML दस्तावेज़ बनाने और उन्हें पाठ (या तो फ़ाइल या मेमोरी) पर लिखने की आवश्यकता है। चूँकि C ++ मानक पुस्तकालय में इसके लिए पुस्तकालय नहीं है, मुझे क्या उपयोग करना चाहिए?

नोट: इसके लिए एक निश्चित, C ++ - FAQ- शैली का प्रश्न है। तो हाँ, यह दूसरों की नकल है। मैंने केवल उन अन्य प्रश्नों को उचित नहीं बताया क्योंकि वे कुछ और अधिक विशिष्ट के लिए पूछना चाहते थे। यह प्रश्न अधिक सामान्य है।


मुझे tiCpp code.google.com/p/ticpp पसंद है , डॉक्स महान (अभी तक?) नहीं हैं, लेकिन मुझे लाइब्रेरी, अच्छा क्लीन कोड बहुत पसंद है।

मैंने अपना खुद का github.com/igagis/mikroxml
igagis

जवाबों:


679

मानक पुस्तकालय कंटेनरों की तरह, आपको किस पुस्तकालय का उपयोग करना चाहिए यह आपकी आवश्यकताओं पर निर्भर करता है। यहाँ एक सुविधाजनक फ़्लोचार्ट है:

यहां छवि विवरण दर्ज करें

तो पहला सवाल यह है: आपको क्या चाहिए?

मुझे फुल XML कम्प्लायंस चाहिए

ठीक है, तो आपको XML को संसाधित करने की आवश्यकता है। एक्सएमएल खिलौना नहीं, असली एक्सएमएल। आपको कम-झूठ, आसान-से-पार्स बिट्स नहीं, बल्कि सभी XML विनिर्देशन को पढ़ने और लिखने में सक्षम होना चाहिए । आपको नामस्थान, DocTypes, इकाई प्रतिस्थापन, कार्यों की आवश्यकता है। W3C XML विशिष्टता, इसकी संपूर्णता में।

अगला सवाल है: क्या आपके एपीआई को DOM या SAX के अनुरूप होना चाहिए?

मुझे सटीक डोम और / या SAX अनुरूपता चाहिए

ठीक है, इसलिए आपको वास्तव में DOM और / या SAX होने के लिए API की आवश्यकता है। यह सिर्फ एक एसएएक्स-शैली पुश पार्सर नहीं हो सकता है, या एक डोम-शैली बरकरार पार्सर हो सकता है। यह वास्तविक DOM या वास्तविक SAX होना चाहिए, जिस सीमा तक C ++ अनुमति देता है।

तुमने पसंद किया:

Xerces

यह तुम्हारा फैसला हैं। यह बहुत ही एकमात्र C ++ XML पार्सर / लेखक है जो पूर्ण है (या C ++ के पास के रूप में अनुमति देता है) DOM और SAX अनुरूपता। इसमें XInclude सपोर्ट, XML स्कीमा सपोर्ट और अन्य फीचर्स का ढेर भी है।

इसकी कोई वास्तविक निर्भरता नहीं है। यह अपाचे लाइसेंस का उपयोग करता है।

मुझे डोम और / या SAX के बारे में परवाह नहीं है

तुमने पसंद किया:

libxml2

LibXML2 एक सी-स्टाइल इंटरफ़ेस प्रदान करता है (यदि वह वास्तव में आपको परेशान करता है, तो Xerces का उपयोग करें), हालांकि इंटरफ़ेस कम से कम कुछ ऑब्जेक्ट-आधारित और आसानी से लिपटा हुआ है। यह बहुत सारी सुविधाएँ प्रदान करता है, जैसे XInclude समर्थन (कॉलबैक के साथ ताकि आप इसे बता सकें कि इसे फ़ाइल कहाँ से मिलती है), एक XPath 1.0 पहचानकर्ता, रिलैक्सएनजी और स्कैमट्रॉन समर्थन (हालांकि त्रुटि संदेश वांछित होने के लिए बहुत कुछ छोड़ते हैं ), और इसके आगे।

यह आइकनव पर निर्भरता रखता है, लेकिन इसे उस निर्भरता के बिना कॉन्फ़िगर किया जा सकता है। हालांकि इसका मतलब यह है कि आपके पास संभव पाठ एन्कोडिंग का अधिक सीमित सेट होगा जो इसे पार्स कर सकता है।

यह MIT लाइसेंस का उपयोग करता है।

मुझे पूर्ण XML अनुपालन की आवश्यकता नहीं है

ठीक है, इसलिए पूर्ण XML अनुपालन आपके लिए कोई मायने नहीं रखता है। आपके XML दस्तावेज़ या तो पूरी तरह से आपके नियंत्रण में हैं या XML के "मूल उपसमूह" का उपयोग करने की गारंटी है: कोई नामस्थान, संस्थाएं आदि नहीं।

तो आपको क्या फर्क पड़ता है? अगला सवाल यह है कि आपके XML कार्य में आपके लिए सबसे महत्वपूर्ण क्या है?

अधिकतम XML पार्सिंग प्रदर्शन

आपके एप्लिकेशन को XML लेने और इसे C ++ डेटास्ट्रक्चर में बदलने की आवश्यकता है क्योंकि यह रूपांतरण संभवतः हो सकता है।

तुमने पसंद किया:

RapidXML

यह XML पार्सर वास्तव में टिन पर यह कहता है: तेजी से XML। यह फ़ाइल को मेमोरी में खींचने से भी संबंधित नहीं है; ऐसा कैसे होता है। इससे निपटने के लिए सी ++ डेटा संरचनाओं की एक श्रृंखला में पार्सिंग है जो आप एक्सेस कर सकते हैं। और यह इसके बारे में उपवास के रूप में फाइल बाइट को स्कैन करने के लिए लेता है।

बेशक, मुफ्त लंच जैसी कोई चीज नहीं है। एक्सएमएल विनिर्देश के बारे में परवाह नहीं करने वाले अधिकांश एक्सएमएल पार्सर की तरह, रैपिड एक्सएमएल नामस्थान, डॉकटेप्स, संस्थाओं (चरित्र संस्थाओं के अपवाद और 6 बुनियादी एक्सएमएल वाले) को नहीं छूता है, और आगे। तो मूल रूप से नोड्स, तत्व, गुण और ऐसे।

इसके अलावा, यह एक DOM- शैली पार्सर है। इसलिए यह आवश्यक है कि आप सभी पाठों को पढ़ें। हालांकि, यह क्या नहीं करता है कि किसी भी पाठ (आमतौर पर) की नकल है । जिस तरह से रैपिडएक्सएमएल को इसकी सबसे अधिक गति मिलती है, वह स्ट्रिंग्स को जगह में संदर्भित करता है । इसके लिए आपकी ओर से अधिक मेमोरी प्रबंधन की आवश्यकता है (रैपिडएक्सएमएल इसे देख रहा है, जबकि आपको उस स्ट्रिंग को जीवित रखना होगा)।

रैपिडएक्सएमएल का डोम नंगे-हड्डियों वाला है। आप चीजों के लिए स्ट्रिंग मान प्राप्त कर सकते हैं। आप नाम से विशेषताएँ खोज सकते हैं। यह इसके बारे में। अन्य मूल्यों (संख्याओं, तिथियों आदि) में विशेषताओं को मोड़ने के लिए कोई सुविधा कार्य नहीं हैं। तुम बस तार हो जाओ।

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

यह MIT लाइसेंस का उपयोग करता है। यह हेडर-ओनली लाइब्रेरी है जिसमें कोई निर्भरता नहीं है।

मैं प्रदर्शन के बारे में परवाह है, लेकिन यह बहुत ज्यादा नहीं है

हां, प्रदर्शन आपके लिए मायने रखता है। लेकिन शायद आपको कुछ कम नंगे-हड्डियों की ज़रूरत है। शायद कुछ ऐसा है जो अधिक यूनिकोड को संभाल सकता है, या इसके लिए उपयोगकर्ता द्वारा नियंत्रित स्मृति प्रबंधन की आवश्यकता नहीं है। प्रदर्शन अभी भी महत्वपूर्ण है, लेकिन आप कुछ कम प्रत्यक्ष चाहते हैं।

तुमने पसंद किया:

PugiXML

ऐतिहासिक रूप से, यह रैपिडएक्सएमएल के लिए प्रेरणा का काम करता है। लेकिन दो परियोजनाओं में बदलाव किया गया है, जिसमें पुगी अधिक सुविधाएँ प्रदान करता है, जबकि रैपिडएक्सएमएल पूरी तरह से गति पर केंद्रित है।

PugiXML यूनिकोड रूपांतरण सहायता प्रदान करता है, इसलिए यदि आपके पास कुछ UTF-16 डॉक्स हैं और उन्हें UTF-8 के रूप में पढ़ना चाहते हैं, तो Pugi प्रदान करेगा। यहां तक ​​कि इसमें XPath 1.0 का कार्यान्वयन भी है, यदि आपको उस प्रकार की आवश्यकता है।

लेकिन पुगी अभी भी काफी तेज है। रैपिडएक्सएमएल की तरह, इसकी कोई निर्भरता नहीं है और एमआईटी लाइसेंस के तहत वितरित किया जाता है।

विशाल दस्तावेज़ पढ़ना

आपको उन दस्तावेजों को पढ़ना होगा जो आकार में गीगाबाइट में मापा जाता है । हो सकता है कि आप उन्हें स्टडिन से प्राप्त कर रहे हों, किसी अन्य प्रक्रिया से खिलाया जा रहा हो। या आप उन्हें बड़े पैमाने पर फ़ाइलों से पढ़ रहे हैं। जो कुछ भी। मुद्दा यह है कि आपको जिस चीज की जरूरत है, उसे प्रोसेस करने के लिए एक बार में पूरी फाइल को मेमोरी में नहीं पढ़ना होगा।

तुमने पसंद किया:

libxml2

Xerces का SAX- स्टाइल API इस क्षमता में काम करेगा, लेकिन LibXML2 यहां है क्योंकि इसके साथ काम करना थोड़ा आसान है। एसएएक्स-स्टाइल एपीआई एक पुश-एपीआई है: यह एक स्ट्रीम पार्स करना शुरू कर देता है और बस उन घटनाओं को बंद कर देता है जिन्हें आपको पकड़ना है। आपको संदर्भ, स्थिति और इसके आगे प्रबंधन करने के लिए मजबूर किया जाता है। कोड जो SAX- शैली API को पढ़ता है, वह एक से अधिक फैल सकता है, जो उम्मीद कर सकता है।

LibXML2 का xmlReaderऑब्जेक्ट पुल-एपीआई है। आप अगले XML नोड या तत्व पर जाने के लिए कहते हैं; आपको नहीं बताया गया है यह आपको संदर्भ को स्टोर करने की अनुमति देता है जैसा कि आप फिट देखते हैं, विभिन्न संस्थाओं को संभालने के लिए कॉलबैक के एक समूह की तुलना में कोड में बहुत अधिक पठनीय है।

वैकल्पिक

प्रवासी

Expat एक प्रसिद्ध C ++ पार्सर है जो पुल-पार्सर एपीआई का उपयोग करता है। इसे जेम्स क्लार्क ने लिखा था।

यह वर्तमान स्थिति सक्रिय है। सबसे हाल का संस्करण 2.2.9 है, जो (2019-09-25) को जारी किया गया था।

LlamaXML

यह एक Stax शैली एपीआई का कार्यान्वयन है। यह एक पुल-पार्सर है, जो कि LibXML2 के xmlReaderपार्सर के समान है ।

लेकिन यह 2005 के बाद से अद्यतन नहीं किया गया है। फिर से, कैविट एम्प्टर।

एक्सपीथ सपोर्ट

XPath एक XML ट्री के भीतर तत्वों को क्वेरी करने के लिए एक प्रणाली है। यह एक मानकीकृत सिंटैक्स का उपयोग करके किसी तत्व या तत्व के संग्रह को प्रभावी ढंग से नाम देने का एक आसान तरीका है। कई XML पुस्तकालयों XPath समर्थन प्रदान करते हैं।

यहां प्रभावी रूप से तीन विकल्प हैं:

  • LibXML2 : यह पूर्ण XPath 1.0 समर्थन प्रदान करता है। फिर से, यह एक सी एपीआई है, इसलिए यदि यह आपको परेशान करता है, तो विकल्प हैं।
  • PugiXML : यह XPath 1.0 सपोर्ट के साथ आता है। ऊपर, यह LibXML2 की तुलना में C ++ API का अधिक है, इसलिए आप इसके साथ अधिक सहज हो सकते हैं।
  • TinyXML : यह XPath सपोर्ट के साथ नहीं आता है, लेकिन TinyXPath लाइब्रेरी है जो इसे प्रदान करती है। TinyXML संस्करण 2.0 में रूपांतरण के दौर से गुजर रहा है, जो एपीआई में काफी बदलाव करता है, इसलिए TinyXPath नए एपीआई के साथ काम नहीं कर सकता है। TinyXML की तरह ही, TinyXPath को zLib लाइसेंस के तहत वितरित किया गया है।

बस नौकरी मिल गई

तो, आप XML शुद्धता के बारे में परवाह नहीं है। प्रदर्शन आपके लिए कोई समस्या नहीं है। स्ट्रीमिंग अप्रासंगिक है। आप बस इतना चाहते हैं कि कुछ ऐसा हो जो XML को मेमोरी में मिल जाए और आपको इसे फिर से डिस्क पर स्टिक करने की अनुमति दे। क्या आप के बारे में परवाह एपीआई है।

आप एक XML पार्सर चाहते हैं जो छोटा, स्थापित करने में आसान, उपयोग करने के लिए तुच्छ और आपके अंतिम निष्पादन योग्य आकार के लिए अप्रासंगिक होने के लिए पर्याप्त छोटा हो।

तुमने पसंद किया:

TinyXML

मैंने टिनीएक्सएमएल को इस स्लॉट में रखा है क्योंकि यह एक्सएमएल पार्सर्स के रूप में उपयोग करने के लिए बहुत सरल है। हां, यह धीमा है, लेकिन यह सरल और स्पष्ट है। विशेषताओं और इसके आगे के रूपांतरण के लिए इसमें बहुत सारे सुविधा कार्य हैं।

XML लिखने से TinyXML में कोई समस्या नहीं है। आप बस newकुछ वस्तुओं को जोड़ते हैं, उन्हें एक साथ संलग्न करते हैं, दस्तावेज़ को भेजते हैं std::ostream, और सभी को खुश करते हैं।

TinyXML के आसपास निर्मित एक पारिस्थितिकी तंत्र की भी कुछ है, अधिक इट्रेटर-फ्रेंडली API के साथ, और यहां तक ​​कि इसके ऊपर स्तरित XPath 1.0 कार्यान्वयन भी।

TinyXML zLib लाइसेंस का उपयोग करता है, जो MIT लाइसेंस को कम या ज्यादा नाम देता है।


6
यह कॉपी-पेस्ट जैसा लगता है। क्या आप स्रोत दस्तावेज़ को लिंक कर सकते हैं?
जोएल

28
@ जॉयल: काफी बार जब कोई व्यक्ति अपने प्रश्न का उत्तर अच्छी लंबी पोस्ट के साथ देता है, तो ऐसा इसलिए है क्योंकि वे जेफ की सलाह का पालन कर रहे हैं - विशेष रूप से इसलिए कि एक अच्छा प्रश्न जैसा दिखने वाला प्रश्न अक्सर एक अच्छे उत्तर से पहले बंद किया जा सकता है। पोस्ट किया जा सकता है, अगर वह व्यक्ति सही उत्तर लिख रहा है तो वहीं। कुछ समय देने के लिए एक प्रतिक्रिया तैयार करने के लिए इससे पहले कि वह सवाल :) निकोल हमें प्रदान कर रहा है पूछा तक सभी के लिए बंद> भविष्य में डुप्लिकेट सवालों के लिए एक उत्कृष्ट उम्मीदवार के साथ।
सरनॉल्ड

28
@Joel: मुझे डर है कि मैं नहीं कर सकता। यह सिर्फ एक अस्थायी दस्तावेज था जिसे मैंने नोटपैड ++ में कॉपी किया था। मैंने इसे कभी नहीं बचाया, इसलिए मैं आपको इससे लिंक नहीं कर सकता;)
निकोल बोलस

6
TinyXML के नए संस्करण का उल्लेख करने योग्य हो सकता है: TinyXML-2 TinyXML-1 के समान API और उसी समृद्ध परीक्षण मामलों का उपयोग करता है। लेकिन एक गेम में उपयोग के लिए इसे अधिक उपयुक्त बनाने के लिए पार्सर के कार्यान्वयन को पूरी तरह से फिर से लिखा गया है। यह कम मेमोरी का उपयोग करता है, तेज है, और बहुत कम मेमोरी एलोकेशन का उपयोग करता है।
जॉन्बेकर्स

6
मुझे यह सवाल और जवाब पसंद है, लेकिन यह भी यूनिक्स-पक्षपाती है। MSXML और XmlLite का कोई उल्लेख नहीं है? यदि मल्टी-पाल्टफॉर्म पोर्टेबिलिटी उन लोगों को बाहर करने का आपका कारण है, तो यह प्रश्न और उत्तर में स्पष्ट रूप से उल्लेख किया जाना चाहिए। (अन्यथा कुछ लोग विंडोज-केवल प्रोजेक्ट के लिए उदाहरण के लिए Libxml2 को चुन सकते हैं, जो सिरदर्द से पूछ रहा है जिसे आसानी से टाला जा सकता था।)
स्क्रेच

17

XML को हैंडल करने का एक और तरीका है जिसे आप XML डेटा बाइंडिंग कह सकते हैं। खासकर यदि आपके पास पहले से ही अपने XML शब्दावली का एक औपचारिक विनिर्देश है, उदाहरण के लिए, XML स्कीमा में।

एक्सएमएल डेटा बाइंडिंग आपको एक्सएमएल का उपयोग करने की अनुमति देता है वास्तव में बिना किसी XML पार्सिंग या धारावाहिककरण के। एक डेटा बाइंडिंग कंपाइलर सभी निम्न-स्तरीय कोड उत्पन्न करता है और पार्स किए गए डेटा को C ++ क्लासेस के रूप में प्रस्तुत करता है जो आपके एप्लिकेशन डोमेन के अनुरूप हैं। तब आप इस डेटा के साथ फ़ंक्शन को कॉल करके और स्ट्रिंग और पार्सिंग टेक्स्ट की तुलना करने के बजाय C ++ प्रकार (int, double, etc) के साथ काम करते हैं (जो कि आप निम्न-स्तरीय XML एक्सेस API जैसे DOM या SAX के साथ करते हैं)।

उदाहरण के लिए, उदाहरण के लिए, एक ओपन-सोर्स XML डेटा बाइंडिंग कार्यान्वयन, जो मैंने लिखा था, कोडसिंथेसिस XSD और, एक हल्के-वजन, निर्भरता-मुक्त संस्करण, कोडसिंथेसिस XSD / e के लिए


13
मुझे इस पोस्ट पर कोई आपत्ति नहीं है, लेकिन एसओ पॉलिसी में कहा गया है कि यदि आप कुछ ऐसा लिखते हैं, तो आपको उल्लेख करना चाहिए कि आपने इसे पूर्ण प्रकटीकरण के हित में लिखा है।
निकोल बोलस

@ नाइकोल मैंने इसे उत्तर में संपादित किया।
JBentley

शायद सहायक इस सूची में है, लेकिन मुझे यह पता नहीं चल पाया कि उस सूची के लेखक (ओं) को सार्वजनिक विवरण के बिना मैं नहीं देख सकता कि क्या विवरण और रेटिंग सार्थक हैं। शायद कोई W3C डेटा बाइंडिंग वर्किंग ग्रुप को देख सकता है जो कई डेटा बाइंडिंग टूल को सूचीबद्ध करता है जो सार्वजनिक डोमेन में हैं और परीक्षण और रिपोर्टिंग के लिए उपयोग किए जाते हैं (पूर्ण प्रकटीकरण: मैं कोडसिंथेसिस से संबद्ध नहीं हूं, मैंने डब्ल्यू 3 सी के साथ सूचीबद्ध गसप को मदद की है। उपकरण)।
डॉ। एलेक्स आरई

1

एक्सपैट के बारे में एक अन्य नोट: यह एम्बेडेड सिस्टम काम के लिए देखने लायक है। हालाँकि, वेब पर आपको मिलने वाले दस्तावेज़ प्राचीन और गलत हैं। स्रोत कोड में वास्तव में पूरी तरह से फ़ंक्शन-स्तरीय टिप्पणियां हैं, लेकिन यह समझ में आने के लिए कुछ भ्रामक लगेगा।


0

मेरा भी डाल दो।

http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-my-XML

कोई XML सत्यापन सुविधाएँ नहीं है, लेकिन तेज़ है।


2
क्या यह रैपिडएक्सएमएल की तुलना में अधिक तेज या व्यापक रूप से उपयोग किया जाता है? या पुगीएक्सएमएल? "फास्ट, नॉट-पूरी तरह से XML" C ++ पार्सर के लिए डोमेन स्पेस बहुत अच्छी तरह से कवर किया गया है।
निकोल बोलस

0

ठीक है फिर। मैंने नया बनाया है, क्योंकि सूची में से कोई भी मेरी जरूरतों को पूरा नहीं करता था।

लाभ:

  1. निचले स्तर पर पुल-पार्सर स्ट्रीमिंग एपीआई ( जावा StAX like )
  2. अपवाद और RTTI समर्थित मोड
  3. मेमोरी उपयोग के लिए सीमा, बड़ी फ़ाइलों के लिए समर्थन (100 mib XMark फ़ाइल के साथ परीक्षण किया गया, गति हार्डवेयर पर निर्भर करती है)
  4. UNICODE समर्थन, और इनपुट स्रोत एन्कोडिंग के लिए ऑटो-डिटेक्टिंग
  5. संरचनाओं / POCO में पढ़ने के लिए उच्च स्तरीय एपीआई
  6. Xml संरचना (गुण और नेस्टिंग टैग) के लिए समर्थन के साथ संरचनाओं / POCO से XSD लिखने और उत्पन्न करने के लिए मेटा-प्रोग्रामिंग API (XSD पीढ़ी को RTTI की आवश्यकता है, लेकिन इसे केवल एक बार बनाने के लिए डीबग पर उपयोग किया जा सकता है)
  7. सी ++ 11 - जीसीसी और वीसी ++ 15+

नुकसान:

  1. डीटीडी और एक्सएसडी सत्यापन अभी तक प्रदान नहीं किए गए हैं
  2. HTTP / HTTPS द्वारा XML / XSD प्राप्त करना प्रगति में है, अभी तक नहीं किया गया है
  3. नई लाइब्रेरी

प्रोजेक्ट घर


1
क्या आप बेंचमार्क जोड़ सकते हैं?
वादिम पेरिटोकिन

-1

में सुरक्षित ग्लोब , Inc उपयोग हम rapidxml । हमने अन्य सभी की कोशिश की, लेकिन रैपिडेक्लेम हमारे लिए सबसे अच्छा विकल्प है।

यहाँ एक उदाहरण है:

 rapidxml::xml_document<char> doc;
    doc.parse<0>(xmlData);
    rapidxml::xml_node<char>* root = doc.first_node();

    rapidxml::xml_node<char>* node_account = 0;
    if (GetNodeByElementName(root, "Account", &node_account) == true)
    {
        rapidxml::xml_node<char>* node_default = 0;
        if (GetNodeByElementName(node_account, "default", &node_default) == true)
        {
            swprintf(result, 100, L"%hs", node_default->value());
            free(xmlData);
            return true;
        }
    }
    free(xmlData);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.