2009-01-21 12 views
6

यह वास्तव में एक प्रश्न नहीं है क्योंकि मुझे पहले से ही एक समाधान मिला है। मुझे बहुत समय लगा, इसलिए मैं इसे यहां समझाऊंगा।पागल बनने के बिना विजुअल स्टूडियो 2008 एक्सप्रेस (कोई एटीएल कक्षाएं) के साथ msxml का उपयोग कैसे करें?

एमएसएक्सएमएल COM पर आधारित है, इसलिए सी ++ में उपयोग करना वास्तव में आसान नहीं है जब भी आपके पास स्मृति आवंटन समस्याओं से निपटने के लिए उपयोगी कक्षाएं हों। लेकिन एक नया एक्सएमएल पार्सर लिखना बहुत मुश्किल होगा इसलिए मैं msxml का उपयोग करना चाहता था।

समस्या:

मैं CComPtr की मदद से msxml उपयोग करने के लिए (स्मार्ट सूचक मैन्युअल रूप से प्रत्येक IXMLDOMNode के लिए रिलीज() कॉल करने के लिए होने से बचने के लिए), CComBSTR इंटरनेट पर पर्याप्त उदाहरण खोजने के लिए सक्षम था (तारों के लिए COM प्रारूप में सी ++ तारों को परिवर्तित करने के लिए) और CComVariant। यह 3 सहायक वर्ग एटीएल कक्षाएं हैं और #include <atlbase.h> की आवश्यकता है।

समस्या: विजुअल स्टूडियो 2008 एक्सप्रेस (मुफ़्त संस्करण) में एटीएल शामिल नहीं है।

समाधान:

उपयोग comutil.h और comdef.h, जो कुछ सरल सहायक वर्गों में शामिल हैं:

  • _bstr_t बदल देता है और अधिक या कम CComBSTR
  • _variant_t बदल देता है और अधिक या कम CComVariant
  • _com_ptr_t की जगह परोक्ष रूप से CComPtr_COM_SMARTPTR_TYPEDEF

छोटे उदाहरण के उपयोग के माध्यम:

#include <msxml.h> 
#include <comdef.h> 
#include <comutil.h> 

// Define some smart pointers for MSXML 
_COM_SMARTPTR_TYPEDEF(IXMLDOMDocument,  __uuidof(IXMLDOMDocument));  // IXMLDOMDocumentPtr 
_COM_SMARTPTR_TYPEDEF(IXMLDOMElement,  __uuidof(IXMLDOMElement));  // IXMLDOMElementPtr 
_COM_SMARTPTR_TYPEDEF(IXMLDOMNodeList,  __uuidof(IXMLDOMNodeList));  // IXMLDOMNodeListPtr 
_COM_SMARTPTR_TYPEDEF(IXMLDOMNamedNodeMap, __uuidof(IXMLDOMNamedNodeMap)); // IXMLDOMNamedNodeMapPtr 
_COM_SMARTPTR_TYPEDEF(IXMLDOMNode,   __uuidof(IXMLDOMNode));   // IXMLDOMNodePtr 

void test_msxml() 
{ 
    // This program will use COM 
    CoInitializeEx(NULL, COINIT_MULTITHREADED); 

    { 
     // Create parser 
     IXMLDOMDocumentPtr pXMLDoc; 
     HRESULT hr = CoCreateInstance(__uuidof (DOMDocument), NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXMLDoc); 
     pXMLDoc->put_validateOnParse(VARIANT_FALSE); 
     pXMLDoc->put_resolveExternals(VARIANT_FALSE); 
     pXMLDoc->put_preserveWhiteSpace(VARIANT_FALSE); 

     // Open file 
     VARIANT_BOOL bLoadOk; 
     std::wstring sfilename = L"testfile.xml"; 
     hr = pXMLDoc->load(_variant_t(sfilename.c_str()), &bLoadOk); 

     // Search for node <testtag> 
     IXMLDOMNodePtr pNode; 
     hr = pXMLDoc->selectSingleNode(_bstr_t(L"testtag"), &pNode); 

     // Read something 
     _bstr_t bstrText; 
     hr = pNode->get_text(bstrText.GetAddress()); 
     std::string sSomething = bstrText; 
    } 

    // I'm finished with COM 
    // (Don't call before all IXMLDOMNodePtr are out of scope) 
    CoUninitialize(); 
} 
+0

वीएस -2008 एक्सप्रेस में एटीएल शामिल नहीं है? वह बेकार है। > :( –

उत्तर

1

मुझे खुशी है कि मैंने अपना प्रश्न पोस्ट किया है हालांकि मेरे पास पहले से ही एक समाधान था क्योंकि मुझे कई वैकल्पिक समाधान मिल गए। आपके सभी उत्तरों के लिए धन्यवाद।

eXpat जैसे अन्य पार्सर का उपयोग करना या शायद छोटा (इतना शक्तिशाली नहीं है लेकिन मेरी ज़रूरतों के लिए पर्याप्त) TinyXML वास्तव में एक अच्छा विचार हो सकता है (और प्रोग्राम को किसी अन्य ऑपरेटिंग सिस्टम पर पोर्ट करना आसान बनाता है)।

कॉम के उपयोग को आसान बनाने के लिए एक #import निर्देश, जाहिरा तौर पर किसी Microsoft विशिष्ट एक्सटेंशन का उपयोग करना भी दिलचस्प है और मेरा पीछा वेब पेज MSXML in C++ but as elegant as in C#, जो कैसे संभव हो उतना msxml के उपयोग को आसान बनाने की व्याख्या करने के लिए लाया।

1

एक अन्य विकल्प एक और XML पार्सर कि पहले से ही किया जाता है, such as eXpat उपयोग करने के लिए होगा। यह एटीएल और COM की जटिलताओं का उपयोग करने से बचाता है, और यह स्वयं को लागू करने से आसान तरीका है। मैं सुझाव देता हूं कि केवल यही कारण है कि आपने कहा है कि एमएसएक्सएमएल पर आप जिस कारण को देख रहे हैं वह इसलिए है क्योंकि आप अपना खुद का पार्सर लागू नहीं करना चाहते हैं।

+0

मैंने पहले ही एक्सएक्सपेट का उपयोग करने के बारे में सोचा था, लेकिन जैसा कि एमएसएक्सएमएल पहले से ही कंप्यूटर पर था, मैंने सोचा था कि इसका उपयोग करके एक छोटा प्रोग्राम बनाने में मदद मिल सकती है। लेकिन अगर मुझे इससे पहले COM कठिनाइयों के बारे में पता था, तो मैंने eXpat का उपयोग किया होगा .. – Name

7

शायद #import कथन का उपयोग करने का प्रयास करें।

मैं एक VS6 परियोजना मैं चारों ओर लटक है में इसका इस्तेमाल किया है, तो आप कुछ इस तरह करते हैं (केवल उदाहरण के उद्देश्यों के लिए है, यह मेरे लिए काम किया, लेकिन मैं त्रुटि सबूत होने का दावा नहीं करते हैं):

#import "msxml6.dll" 

    ... 

MSXML2::IXMLDOMDocument2Ptr pdoc; 
HRESULT hr = pdoc.CreateInstance(__uuidof(MSXML2::DOMDocument60)); 
if (!SUCCEEDED(hr)) return hr; 

MSXML2::IXMLDOMDocument2Ptr pschema; 
HRESULT hr = pschema.CreateInstance(__uuidof(MSXML2::DOMDocument60)); 
if (!SUCCEEDED(hr)) return hr; 

pschema->async=VARIANT_FALSE; 
VARIANT_BOOL b; 
b = pschema->loadXML(_bstr_t(/* your schema XML here */)); 

MSXML2::IXMLDOMSchemaCollection2Ptr pSchemaCache; 
hr = pSchemaCache.CreateInstance(__uuidof(MSXML2::XMLSchemaCache60)); 
if (!SUCCEEDED(hr)) return hr; 

_variant_t vp=pschema.GetInterfacePtr(); 
pSchemaCache->add(_bstr_t(/* your namespace here */),vp); 

pdoc->async=VARIANT_FALSE; 
pdoc->schemas = pSchemaCache.GetInterfacePtr(); 
pdoc->validateOnParse=VARIANT_TRUE; 
if (how == e_filename) 
    b = pdoc->load(v); 
else 
    b = pdoc->loadXML(bxmldoc); 

pXMLError = pdoc->parseError; 
if (pXMLError->errorCode != 0) 
    return E_FAIL; // an unhelpful return code, sigh.... 
+0

# आयात बहुत आसान तरीका है, लिखने के लिए आसान और बहुत कम कोड – galets

+0

मैंने पहले "#import" के बारे में नहीं सुना था (सी ++ के साथ मैंने अब तक विंडोज के मुकाबले यूनिक्स के तहत अधिक समय व्यतीत किया है)। बहुत ही रोचक लगता है। – Name

0

आप कुछ एमएसएक्सएमएल रैपर का उपयोग क्यों नहीं करते हैं जो आपको COM12, जैसे Arabica बनाता है?

+0

आपके उत्तर के लिए धन्यवाद। लेकिन मैं वास्तव में एक्सएमएल पार्सर का उपयोग करने के लिए संकेत की एक परत जोड़ना नहीं चाहता हूं। – Name

1

आप TinyXML का उपयोग कर सकते हैं। यह खुला स्रोत है और मंच पर अधिक स्वतंत्र है।

+0

दिलचस्प, मैंने पहले इस पार्सर के बारे में नहीं सुना था। यह एक "प्रकाश हो सकता है "एक्सपैप के विकल्प (मैंने जांच नहीं की है कि कितने संसाधनों की आवश्यकता है)। – Name