加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何将msxml与Visual Studio 2008 Express(没有ATL类)一起

发布时间:2020-12-16 03:38:11 所属栏目:百科 来源:网络整理
导读:这不是一个问题,因为我已经找到了解决方案.我花了很多时间,这就是我想在这里解释的原因. Msxml基于COM,所以即使你有一些有用的类来处理内存分配问题,它也不是很容易在C中使用.但是编写一个新的XML解析器要困难得多,所以我想使用msxml. 问题: 我能够在互联网
这不是一个问题,因为我已经找到了解决方案.我花了很多时间,这就是我想在这里解释的原因.

Msxml基于COM,所以即使你有一些有用的类来处理内存分配问题,它也不是很容易在C中使用.但是编写一个新的XML解析器要困难得多,所以我想使用msxml.

问题:

我能够在互联网上找到足够的例子,在CComPtr的帮助下使用msxml(智能指针避免必须手动调用每个IXMLDOMNode的Release()),CComBSTR(将C字符串转换为字符串的COM格式)和CComVariant .这3个有用的类是ATL类,需要#include< atlbase.h>.

问题:Visual Studio 2008 Express(免费版)不包含ATL.

解:

使用comutil.h和comdef.h,其中包含一些简单的帮助器类:

> _bstr_t或多或少取代CComBSTR
> _variant_t或多或少取代CComVariant
> _com_ptr_t通过使用_COM_SMARTPTR_TYPEDEF间接替换CComPtr

小例子:

#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();
}

解决方法

也许尝试使用#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....

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读