您的位置:威尼斯官方网站 > 威尼斯正规官网 > 只要您要在C/C++程序里处理XML如何是好呢

只要您要在C/C++程序里处理XML如何是好呢

发布时间:2020-01-04 07:04编辑:威尼斯正规官网浏览(60)

    写Unmanaged Code在.NET年代成为生龙活虎种好惨烈的事,当您需求处理XML文件时,这种感到会变得更为明显。FCL中的System.Xml多轻巧啊,连SteveBallmer都知情怎么用。

    事务不会接连那么非凡的,要是你要在C/C++程序里管理XML咋办吧?

    分选意气风发:市道上的XML lib依然有多少个的,最著名的自然是libxml。小编一年前用过,十分不利,作者还特意写了风华正茂份肯定教程,后来不知搁哪里了。

    慎选二:MS的MSXML,笔者要介绍的就是以此。

    先说一下在MSDN何地找文书档案吧,往下看的时候能够有个参谋:在Index里打:Windows Media Services 9 Series SDK=>Programming Reference=>Programming Reference (C++卡塔尔国=>XML DOM Interfaces (C++卡塔尔国。什么?Windows Media?呵呵,不错,作者认为那几个guide反而是最驾驭的,你一向找MSXML,获得的结果,笔者以为还未有这些好。

    在C程序里调用MSXML基本正是一群COM接口,可是在Visual Studio里操作先要做点轻巧的设置:

    在您的Project里Add References=>COM标签=>Microsoft XML v4.0,5.0实际上也是有了,但因为是和Office一同发表的,以为多少怪,不想用,反正也未必用哪些很奇妙的效率,4.0方可了。

    接下来在加盟这两行:

    #include
    #import

    头文件和dll库。什么?在哪里加?头文件或许c/cpp文件啊,什么地方合适放哪个地方。

    下一场就开首编制程序了,先定义四个必用的变量:

    IXMLDOMDocumentPtr xmlFile = NULL;
    IXMLDOMElement* xmlRoot = NULL;

    何以是必用的?  汗...

    先是步当然是伊始化COM:

    if(FAILED(CoInitialize(NULL))) ....

    接下去初始化xmlFile对象:

    if(FAILED(xmlFile.CreateInstance("Msxml2.DOMDocument.4.0"))) ...

    下一场就能够加载xml文件了:

    _variant_t varXml(L"C:\test.xml"); //L for unicode
    VARIANT_BOOL varOut;
    xmlFile->load(varXml, &varOut);

    取得root element:

    xmlFile->get_documentElement(&xmlRoot))

    拿到第顶尖element:

    IXMLDOMNodeList* xmlChildNodes = NULL;
    xmlRoot->get_childNodes(&xmlChildNodes);

    遍历全体第一流element:

    IXMLDOMNode* currentNode = NULL;
    while(!FAILED(xmlChildNodes->nextNode(¤tNode)) && currentNode != NULL)
    {
    //do something
    }

    获取当前element的称谓:

    BSTR nodeName;
    currentNode->get_nodeName(&nodeName);

    获得当前element的三个attribute(即便这一个attribute叫type)的值:

    IXMLDOMNamedNodeMap* attributes = NULL;
    IXMLDOMNode* attributeName = NULL;
    _bstr_t bstrAttributeName = "type";
    BSTR nameVal;
    currentNode->get_attributes(&attributes);
    attributes->getNamedItem(bstrAttributeName, &attributeName);
    attributeName->get_text(&nameVal);

    内需注意的是,你要记住释放具备的假说,IXMLDOM***->Release(卡塔尔国,这可不是.NET,有人帮您GC,你得和煦调用Release(卡塔尔来减reference count,it's COM, remember?

    好了,大概就这么,顺便提一下XPath:

    _bstr_t bstrXmlQuery = L"/books/book[@type=scifi and @author=fox]";
    IXMLDOMNodeList* nodes = NULL;
    if(FAILED(xmlRoot->selectNodes(bstrXmlQuery, &nodes)) || FAILED(nodes->get_length(&length)) || length == 0)
    //no match found or something went wrong
    else
    //match found

    下面是找这样的node:

    ....

    ....

    切切实实的XPath语法就查手册吧,随地皆有。

    哦,对了,忘了说:倘若你一切用ATL的类的话,借口的调用会轻易一点,可是相当轻松转换的,举例:

    IXMLDOMDocument* 对应 IXMLDOMDocumentPtr(我这里用了),别的主题也是加个Ptr,笔者不赘述了。

    最终提供一个sample,笔者有时攒的。工作的时候写的次第当然无法拿来贴的,呵呵。那个sample基本就是遍历整个xml,然后告诉贰遍文件的构造,对各个node,假诺它有叁个叫id的attribute,就同期打字与印刷id的值。If you want the complete VS project, shoot me an email. But I guess no one really needs it anyway, right, : State of Qatar

    #include "stdafx.h"
    #include
    #include
    #import

    HANDLE logFile = NULL;

    #define INDENT 4

    #define TESTHR(hr)
    {
    if(FAILED(hr)) goto fail;
    }

    void PrintChild(IXMLDOMNodeList* nodeList, int level)
    {
    if(nodeList == NULL)
    威尼斯官方网站,return;

    IXMLDOMNode* currentNode = NULL;
    IXMLDOMNodeList* childNodes = NULL;
    IXMLDOMNamedNodeMap* attributes = NULL;
    IXMLDOMNode* attributeID = NULL;

    while(!FAILED(nodeList->nextNode(¤tNode)) && currentNode != NULL)
    {
    BSTR nodeName;
    TESTHR(currentNode->get_nodeName(&nodeName));
    DWORD dwBytesWritten;
    for(int i=0; i WriteFile(logFile, L" ", (DWORD)(sizeof(WCHAR)), &dwBytesWritten, NULL);

    //WCHAR msg[MAX_SIZE];
    //wsprintf(msg, L"%s ", nodeName);
    WriteFile(logFile, nodeName, (DWORD)(wcslen(nodeName)*sizeof(WCHAR)), &dwBytesWritten, NULL);

    TESTHR(currentNode->get_attributes(&attributes));
    if(attributes!=NULL)
    {
    _bstr_t bstrAttributeName = "id";
    BSTR idVal;
    TESTHR(attributes->getNamedItem(bstrAttributeName, &attributeID));
    if(attributeID != NULL)
    {
    TESTHR(attributeID->get_text(&idVal));
    WriteFile(logFile, L" ", (DWORD)(sizeof(WCHAR)), &dwBytesWritten, NULL);
    WriteFile(logFile, idVal, (DWORD)(wcslen(idVal)*sizeof(WCHAR)), &dwBytesWritten, NULL);
    WriteFile(logFile, L"rn", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);
    attributeID->Release(); attributeID = NULL;
    }
    else
    {
    WriteFile(logFile, L"rn", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);
    }
    attributes->Release(); attributes = NULL;

    }
    else
    {
    WriteFile(logFile, L"rn", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);
    }

    TESTHR(currentNode->get_childNodes(&childNodes));
    PrintChild(childNodes, level+1);
    currentNode=NULL;
    }

    fail:
    if(childNodes!=NULL)
    childNodes->Release();
    if(attributeID!=NULL)
    attributeID->Release();
    if(attributes!=NULL)
    attributes->Release();
    if(currentNode != NULL)
    currentNode->Release();
    }

    int _tmain(int argc, _TCHAR* argv[])
    {

    IXMLDOMDocumentPtr xmlFile = NULL;
    IXMLDOMElement* xmlRoot = NULL;
    _variant_t varXml(L"C:\demo1.xml");

    logFile = CreateFile(L"log.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(logFile == INVALID_HANDLE_VALUE)
    goto fail;

    TESTHR(CoInitialize(NULL));

    TESTHR(xmlFile.CreateInstance("Msxml2.DOMDocument.4.0"));

    VARIANT_BOOL varOut;
    TESTHR(xmlFile->load(varXml, &varOut));

    TESTHR(xmlFile->get_documentElement(&xmlRoot));

    BSTR rootName;
    DWORD dwBytesWritten;
    TESTHR(xmlRoot->get_nodeName(&rootName));
    WriteFile(logFile, rootName, (DWORD)(wcslen(rootName)*sizeof(WCHAR)), &dwBytesWritten, NULL);
    WriteFile(logFile, L"rn", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);

    IXMLDOMNodeList* xmlChildNodes = NULL;
    TESTHR(xmlRoot->get_childNodes(&xmlChildNodes));

    PrintChild(xmlChildNodes, 2);

    fail:
    if(logFile != INVALID_HANDLE_VALUE)
    CloseHandle(logFile);
    if(xmlChildNodes!=NULL)
    xmlChildNodes->Release();
    if(xmlRoot!=NULL)
    xmlRoot->Release();
    return 0;
    }

    本文由威尼斯官方网站发布于威尼斯正规官网,转载请注明出处:只要您要在C/C++程序里处理XML如何是好呢

    关键词:

上一篇:2.0 中 iterator block 机制的达成原理

下一篇:没有了