奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> XML >> C++中处理XML文件
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • .Net的精髓XML和SOAP简

  • 使用XMLHTTP制作域名查

  • 什么是XML

  • XML for Analysis 规范

  • XML for Analysis 规范

  • XML for Analysis 规范

  • 修改大型 XML 文件的有

  • 通过xalan实现关系型数

  • C++中处理XML文件
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-20

    写Unmanaged Code在.NET时代成为一种很悲惨的事,当你需要处理XML文件时,这种感觉会变得尤其强烈。FCL中的System.Xml多简单啊,连Steve Ballmer都知道怎么用。

    事情不会总是那么理想的,如果你要在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 <msxml2.h>
    #import <msxml4.dll>

    头文件和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(&currentNode)) && 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:

    <books>
    <book type="scifi" author="fox">....
    </book>
    ....
    </books>

    具体的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, : )

    #include "stdafx.h"
    #include <windows.h>
    #include <msxml2.h>
    #import <msxml4.dll>

    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(&currentNode)) && currentNode != NULL)
    {
    BSTR nodeName;
    TESTHR(currentNode->get_nodeName(&nodeName));
    DWORD dwBytesWritten;
    for(int i=0; i<level*INDENT; 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"\r\n", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);
    attributeID->Release(); attributeID = NULL;
    }
    else
    {
    WriteFile(logFile, L"\r\n", (DWORD)(2*sizeof(WCHAR)), &dwBytesWritten, NULL);
    }
    attributes->Release(); attributes = NULL;

    }
    else
    {
    WriteFile(logFile, L"\r\n", (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"\r\n", (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;
    }

    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.