VC++中操作XML(MFC、SDK)
C++中的XML和JSON处理
![C++中的XML和JSON处理](https://img.taocdn.com/s3/m/449dfd63cec789eb172ded630b1c59eef8c79ab6.png)
C++中的XML和JSON处理在C++中,XML和JSON是两种常用的数据格式,可以用来存储和传输结构化数据。
XML(可扩展标记语言)是一种标记语言,而JSON (JavaScript对象表示)是一种数据交换格式。
它们都具有易读、易解析的特性,被广泛应用于网络通信、配置文件、数据存储等方面。
首先我们来看一下XML在C++中的处理。
C++有一些开源的XML库可以用来解析和生成XML数据,其中较为常用的有Xerces-C++、TinyXML、RapidXML等。
这些库提供了丰富的API和功能,可以方便地读取、修改和生成XML文档。
Xerces-C++是一个功能强大的XML解析库,支持DOM(文档对象模型)和SAX(简单API for XML)两种解析方式。
DOM方式以树状结构表示XML文档,允许很方便地遍历和修改XML数据;而SAX方式则是一种事件驱动的解析方式,逐行解析XML文档,适用于大型XML文档的处理。
Xerces-C++还提供了一些辅助函数用于生成XML文档,并且支持XPath等高级查询语言。
TinyXML是一个轻量级的XML解析库,简单易用。
它使用C++的对象模型来表示XML文档,可以方便地读取和修改XML数据。
TinyXML没有SAX解析方式,但提供了较为简单的DOM接口,适用于小型XML文档的处理。
TinyXML还支持XPath查询,方便地对XML文档进行高级查询操作。
RapidXML同样是一个轻量级的XML解析库,性能优异。
它使用模板技术来实现解析功能,具有较高的解析速度和低的内存占用。
RapidXML使用指针和迭代器来遍历XML文档,适用于大型XML文档的处理。
不过,相较于Xerces-C++和TinyXML,RapidXML的API相对简单,不支持DOM方式和XPath查询。
接下来我们来看一下JSON在C++中的处理。
C++同样有一些开源的JSON库可以用来解析和生成JSON数据,其中比较常用的有RapidJSON、JSON for Modern C++、nlohmann/json等。
VC++ xml解析
![VC++ xml解析](https://img.taocdn.com/s3/m/157205b9c77da26925c5b0b9.png)
三种最流行的开放源码XML 库是expat、libxml 和Xerces。
第一部分:DOM解析:概述:DOM解析将会把一个完整的XML文档读进来,生成一个结构树。
这样会要把XML文档全部都加载到内在中。
所以解析起来的速度会要慢一些。
1、如何加载xml文件://创建DOM,加载XML文档MSXML::IXMLDOMDocumentPtr pCommandDoc;pCommandDoc.CreateInstance(__uuidof(MSXML::DOMDocument));pCommandDoc->put_async(V ARIANT_FALSE);pCommandDoc->put_validateOnParse(VARIANT_FALSE);pCommandDoc->put_resolveExternals(V ARIANT_FALSE);pCommandDoc->put_preserveWhiteSpace(V ARIANT_TRUE);pCommandDoc->load(file.GetBuffer(0));2、在XML文档中查找指定的结点://找到MSXML::IXMLDOMNodePtrpRootNode=pCommandDoc->selectSingleNode("root/record");if (pRootNode==NULL){return ;}3、得到XML文档中,结点的属性CString strTemp;MSXML::IXMLDOMNamedNodeMapPtr pAttrs = NULL;pRootNode->get_attributes(&pAttrs);if (pAttrs==NULL){return;}MSXML::IXMLDOMNodePtr pRequestTypeAttr=pAttrs->getQualifiedItem("name","");_bstr_t strRequestType=pRequestTypeAttr->Gettext();strTemp=strRequestType.operator char *();4、得到结点的内容_bstr_t strVisiPort=pNode->Gettext();5、设置结点的内容HRESULT hr=pNode->put_text(_bstr_t(m_strGatewayPassword));6、设置一个属性内容IXMLDOMAttribute *pa=NULL;bstr = SysAllocString(L"属性1");pXMLDom->createAttribute(bstr,&pNode);var = VariantString(L"strin");pa->put_value(var);pRoot->setAttributeNode(pa, &pa1);第二部分、如何使用SAX解析概述:SAX使用的是加载式的,将会把XML文档分断,加载到内存中。
VC++中使用MFC通过ADO连接数据库
![VC++中使用MFC通过ADO连接数据库](https://img.taocdn.com/s3/m/8106e216f18583d04964593d.png)
VC++中使用MFC通过ADO连接数据库VC++中使用MFC通过ADO连接数据库一.让我们看看ADO数据库访问技术使用的基本步骤及方法:1.首先,要用#import语句来引用支持ADO的组件类型库(*.tlb),其中类型库可以作为可执行程序(DLL、EXE等)的一部分被定位在其自身程序中的附属资源里,如:被定位在msado15.dll的附属资源中,只需要直接用 #import引用它既可。
可以直接在Stdafx.h文件中加入下面语句来实现:#import "c:/program files/common files/system/ado/msado15.dll"no_namespace rename("EOF", "adoEOF") 【注意,在MFC中路径要用"/"或者"//"】其中路径名可以根据自己系统安装的ADO支持文件的路径来自行设定。
当编译器遇到#import语句时,它会为引用组件类型库中的接口生成包装类,#import语句实际上相当于执行了API涵数LoadTypeLib()。
#import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID等进行声明,创建一系列包装方法。
语句no_namespace说明ADO对象不使用命名空间,rename ("EOF", "adoEOF")说明将ADO中结束标志EOF改为adoEOF,以避免和其它库中命名相冲突。
2.其次,在程序初始过程中需要初始化组件,一般可以用CoInitialize(NULL);来实现,这种方法在结束时要关闭初始化的COM,可以用下面语句CoUnInitialize();来实现。
VC++MFC基础教程
![VC++MFC基础教程](https://img.taocdn.com/s3/m/c1e5197a01f69e31433294eb.png)
dcb.Parity=NOPARITY; //无奇偶校验位 dcb.StopBits=TWOSTOPBITS; //两个停止位 SetCommState(hCom,&dcb);
m_cComm.put_OutBufferSize(512); //设置输出缓冲区 m_cComm.put_Settings(TEXT("9600,n,8,1"));//波特率,无校验,个数
据位,个停止位
if(!m_cComm.get_PortOpen())
{
m_cComm.put_PortOpen(TRUE); //打开串口
B)修改控件属性
修改上面的示例编辑框属性: ID——IDC_EDIT_RECV;
Multiline——True; Want Return——True; Vertical Scroll——True; Auto VScroll——True;
修改下面的示例编辑框属性: ID——IDC_EDIT_SEND; Multiline——True; Vertical Scroll——True;
1.3、API 串口编程
按照步骤一新建 Serial 工程,这里不赘述了。
A)添加 API 串口初始化代码
1、在 SerialDlg.cpp 文件中添加全局变量:
HANDLE hCom; //全局变量,串口句柄 // CSerialDlg 对话框
2、在 SerialDlg.cpp 文件中的 OnInitDialog()函数添加如下代码:
AfxMessageBox("写串口失败!"); }
MFC、SDK和API有什么区别
![MFC、SDK和API有什么区别](https://img.taocdn.com/s3/m/36047ebbf121dd36a32d8220.png)
MFC是微软的基本类库,对很多东西已经进行了封装,因此使用起来简单、方便。SDK是采用较一般的C语言,但很灵活。
般编写简单的程序,使用MFC应该能达到要求。但如果编写功能强大的程序,则使用SDK较多,尤其是底层的开发。
SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”。这是一个覆盖面相当广泛的名词,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”。我们后面只讨论广义 SDK 的一个子集——即开发 Windows 平台下的应用程序所使用的 SDK。
附带地,这里简单地给出MFC和 API及 SDK三者的关系:
MFC是一个类库,主要完成对WIN32 API 的封装,SDK是一个WIN32应用程序开发包,里面包含了开发WIN32应用程序所需的API声明,API是微软提供的WIN32应用程序接口.
简单说,API是接口,SDK是包含API声明的开发包,MFC是封装API的类库.
我们仍然用VC6的IDE(集成开发环境)来编写SDK程序,启动VC6后选择File菜单的New...选项,在出现的New对话框的Projects标签内选择Win32 Application,然后在Projects Name指定项目的名字,在Location中指定路径后按OK按钮,在出现的对话框中,如果你想要用C语言来写程序可以选择An emtpy project,如果你想创建一个带有WinMain入口函数和普通参数的设定的项目,可以选择A simple Win32 application,如果您想创建一个简单典型的“Hello World!”Win32SDK application应用程序,可以选择A typical "Hello World!" application。确定项目类型后按Finish完成。 在VC6环境下,你依然可以使用资源编辑器和ClassWizar等工具完成程序的编写。用SDK编写程序关键是能够了解程序的来龙去脉。如果不了解,当然那样效率会很低,不比VB、PB那么快,任何东西都是有得有失,如你熟悉用SDK写程序后,对MFC会比较容易上手的,关键要熟悉C++的三大特性
MFC中使用SDK个人经验总结(包含海康威视云台相机)
![MFC中使用SDK个人经验总结(包含海康威视云台相机)](https://img.taocdn.com/s3/m/87f07afc81c758f5f61f673e.png)
dlgdata.cpp Line 40 的问题首先打开C->PROGRAM FILE(X86)->Microsoft Visual Studio 11.0->VC->atlmfc->src->mfc->dlgdata.cpp打开,并在LINE40添加断点,调试找出nIDC的值,然后解决问题!如果在resource.h中找不到对应ID,又或者更改过resource.h,出现异常,应删除debug 文件夹,重新生成解决方案!!!重新生成!1.项目属性中“C/C++”->“常规”->“附加包含目录”添加SDK包中的头文件;2.项目属性中“链接器”->“常规”->“附加库目录”把对应的文件夹位置添加进去;3.项目属性中“链接器”->"输入"->“附加依赖项”添加相应的lib文件名。
4.在C***Dlg.h中添加头文件#include"GeneralDef.h"5.在C***App的初始化程序InitInstance()中添加SDK的初始化程序NET_DVR_Init();6.添加成员变量:播放句柄变量LONG m_lPlayHandle; 播放句柄用于判断是否播放正常以及作为NET_DVR_StopRealPlay等函数的句柄参数。
添加成员变量DWORD m_fault_code;BOOL m_bIsLogin;BOOL m_bIsPlaying;STRU_DEVICE_INFO m_struDeviceInfo;并在构造函数中对其初始化m_lPlayHandle = -1;m_fault_code = 0;m_bIsLogin = FALSE;m_bIsPlaying = FALSE;7.在C***Dlg.cpp中添加全局变量char DeviceIp[13] = "192.168.1.11";char UserName[6] = "admin";char Password[10] = "xde123456";WORD DeviceIpPort = 8000;8.单按钮启动if(!m_bIsLogin){NET_DVR_DEVICEINFO_V30 DeviceInfoTmp;memset(&DeviceInfoTmp,0,sizeof(NET_DVR_DEVICEINFO_V30));LONG lLoginID = NET_DVR_Login_V30(DeviceIp , DeviceIpPort, UserName, Password,&DeviceInfoTmp);if(lLoginID == -1){CString strTemp;strTemp.LoadStringW(IDS_STRING_0_LOGIN_STATUS);MessageBox(strTemp);return;}m_bIsLogin = TRUE;m_struDeviceInfo.lLoginID = lLoginID;m_struDeviceInfo.iDeviceChanNum = DeviceInfoTmp.byChanNum;m_struDeviceInfo.iIPChanNum = DeviceInfoTmp.byIPChanNum;m_struDeviceInfo.iStartChan = DeviceInfoTmp.byStartChan;m_struDeviceInfo.iIPStartChan = DeviceInfoTmp.byStartDChan;}if(!m_bIsPlaying){NET_DVR_PREVIEWINFO ClientInfo = {0};ClientInfo.lChannel = 1;//选择预览的窗口句柄ClientInfo.hPlayWnd = GetDlgItem(IDC_0_STATIC_CAMERA)->m_hWnd;m_lPlayHandle = NET_DVR_RealPlay_V40(m_struDeviceInfo.lLoginID, &ClientInfo, NULL, NULL);//预览播放成功返回非负数,失败返回-1if(m_lPlayHandle >= 0){m_bIsPlaying = TRUE;CString strTemp;strTemp.LoadStringW(IDS_STRING_0_PLAY_BUTTON_STATUS2);GetDlgItem(IDC_0_PLAY)->SetWindowText(strTemp);this->SetTimer(Timer_Camera_Connect_Detection, 1000, NULL);}else{CString strTemp1;strTemp1.LoadStringW(IDS_STRING_0_PLAY_STATUS);CString strTemp2;m_fault_code = NET_DVR_GetLastError();strTemp2.Format(L"%d", m_fault_code);CString strTemp3;strTemp3.LoadStringW(IDS_STRING_0_PLAY_FAULT_CODE);CString strTemp4;strTemp4 = strTemp1 + L", " + strTemp3 + strTemp2;MessageBox(strTemp4);return;}}else{m_bIsPlaying = FALSE;CString strTemp;strTemp.LoadStringW(IDS_STRING_0_PLAY_BUTTON_STATUS1);GetDlgItem(IDC_0_PLAY)->SetWindowText(strTemp);NET_DVR_StopRealPlay(m_lPlayHandle);m_lPlayHandle = -1;GetDlgItem(IDC_0_STATIC_CAMERA)->Invalidate();}云台控制1.添加一个基于CButton的CPTZButton类,2.在头文件中添加以下声明#if !defined(AFX_PTZBUTTON_H__B3E99438_BBCE_4862_845F_D3AB668824A6__INCLUDED_) #define AFX_PTZBUTTON_H__B3E99438_BBCE_4862_845F_D3AB668824A6__INCLUDED_#if_MSC_VER > 1000#pragma once#endif// _MSC_VER > 1000并在头文件的结尾加上#endif3.添加成员变量int m_iSubBtnIndex; //功能按钮的索引号,添加按钮类时自动+1,用于对应相应功能添加成员函数void PTZControlAll(LONG lRealHandle,DWORD dwPTZCommand,DWORD dwStop ,int Speed); //用于实现各按钮的功能4.添加全局变量int g_iPtzBtnIndex = 0;在构造函数中对m_iSubBtnIndex进行初始化m_iSubBtnIndex = g_iPtzBtnIndex++;5.通过类向导,添加消息处理函数OnLButtonDown和OnLButtonUp;6.在PTZButton.cpp中添加***app的头文件,并添加声明#ifdef_DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif7.在按钮所在画面的类中添加两个函数,用于获得预览窗口的句柄以及云台移动的速度。
手把手教你VC上位机MFC利用串口控件发送接收数据
![手把手教你VC上位机MFC利用串口控件发送接收数据](https://img.taocdn.com/s3/m/b38e012b2af90242a895e582.png)
1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest;2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX 一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #i nclude "mscomm.h"//}}AFX_INCLUDES 。
4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
MFC控件使用方法
![MFC控件使用方法](https://img.taocdn.com/s3/m/fcbf5b73bf23482fb4daa58da0116c175f0e1ec1.png)
MFC控件使用方法VC2012下MFC程序各控件的常用方法分类:vc控件2013-02-16 16:32 94人阅读评论(0) 收藏举报一下控件的用法全部在VC2012下调试通过,特发文收藏(部分内容来自或参考自网络):Static Text:将ID号改成唯一的一个,如:IDC_XX,然后进一次类向导点确定产生这个ID,之后更改Caption属性:GetDlgItem(IDC_XX)->SetWindowText(L"dsgdhfgdffd");设置字体:CFont *pFont= new CFont;pFont->CreatePointFont(120,_T("华文行楷"));GetDlgItem(IDC_XX)->SetFont(pFont);Edit Control:设置文本:SetDlgItemT ext(IDC_XX,L"iuewurebfdjf");获取所有输入:建立类向导创建一个成员变量(假设是shuru1,shuru2……)类型选value,变量类型任选。
UpdateData(true);GetDlgItem(IDC_XX)->SetWindowText(shuru1);第一句更新所有建立了变量的对话框组件,获取输入的值。
第二句将前面的IDC_XX的静态文本内容改为shuru1输入的内容。
若类型选用control:1.设置只读属性:shuru1.SetReadOnly(true);2.判断edit中光标状态并得到选中内容(richedit同样适用)int nStart,nEnd;CString strTemp;shuru1.GetSel(nStart,nEnd);if(nStart== nEnd){strTemp.Format(_T("光标在%d" ),nStart);AfxMessageBox(strTemp);}else{//得到edit选中的内容shuru1.GetWindowText(strTemp);strTemp= strTemp.Mid(nStart,nEnd-nStart);AfxMessageBox(strTemp);}其中nStart和nEnd分别表示光标的起始和终止位置,从0开始。
VC6.0里面MFC控件CListCtrl的一些常用用法
![VC6.0里面MFC控件CListCtrl的一些常用用法](https://img.taocdn.com/s3/m/740cc919773231126edb6f1aff00bed5b9f37382.png)
VC6.0⾥⾯MFC控件CListCtrl的⼀些常⽤⽤法CListCtrl 使⽤技巧以下未经说明,listctrl默认view 风格为report相关类及处理函数MFC:CListCtrl类SDK:以 “ListView_”开头的⼀些宏。
如 ListView_InsertColumn1. CListCtrl 风格LVS_ICON: 为每个item显⽰⼤图标LVS_SMALLICON: 为每个item显⽰⼩图标LVS_LIST: 显⽰⼀列带有⼩图标的itemLVS_REPORT: 显⽰item详细资料直观的理解:windows资源管理器,“查看”标签下的“⼤图标,⼩图标,列表,详细资料2. 设置listctrl 风格及扩展风格3. 插⼊数据m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插⼊列m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );int nRow = m_list.InsertItem(0, “11”);//插⼊⾏m_list.SetItemText(nRow, 1, “jacky”);//设置数据4. ⼀直选中item选中style中的Show selection always,或者在上⾯第2点中设置LVS_SHOWSELALWAYS5. 选中和取消选中⼀⾏int nIndex = 0;//选中m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);//取消选中m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);6. 得到listctrl中所有⾏的checkbox的状态m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);CString str;for(int i=0; i {if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i)){str.Format(_T("第%d⾏的checkbox为选中状态"), i);AfxMessageBox(str);}}7. 得到listctrl中所有选中⾏的序号⽅法⼀:CString str;for(int i=0; i {if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED ) {str.Format(_T("选中了第%d⾏"), i);nbsp; AfxMessageBox(str);}}⽅法⼆:POSITION pos = m_list.GetFirstSelectedItemPosition();if (pos == NULL)TRACE0("No items were selected!\n");else{while (pos){int nItem = m_list.GetNextSelectedItem(pos);TRACE1("Item %d was selected!\n", nItem);// you could do your own processing on nItem here}}8. 得到item的信息TCHAR szBuf[1024];LVITEM lvi;lvi.iItem = nItemIndex;lvi.iSubItem = 0;lvi.mask = LVIF_TEXT;lvi.pszText = szBuf;hTextMax = 1024;m_list.GetItem(&lvi);9. 得到listctrl的所有列的header字符串内容LVCOLUMN lvcol;char str[256];int nColNum;CString strColumnName[4];//假如有4列nColNum = 0;lvcol.mask = LVCF_TEXT;lvcol.pszText = str;hTextMax = 256;while(m_list.GetColumn(nColNum, &lvcol)){strColumnName[nColNum] = lvcol.pszText;nColNum++;}10. 使listctrl中⼀项可见,即滚动滚动条m_list.EnsureVisible(i, FALSE);11. 得到listctrl列数int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();12. 删除所有列⽅法⼀:while ( m_list.DeleteColumn (0))因为你删除了第⼀列后,后⾯的列会依次向上移动。
vc后缀名说明
![vc后缀名说明](https://img.taocdn.com/s3/m/945a3f1fc281e53a5802ff0b.png)
●sln:解决方案文件,为解决方案资源管理器提供显示管理文件的图形接口所需的信息。
●csproj:项目文件,创建应用程序所需的引用、数据连接、文件夹和文件的信息。
●.aspx:Web 窗体页由两部分组成:视觉元素(HTML、服务器控件和静态文本)和该页的编程逻辑。
Visual Studio 将这两个组成部分分别存储在一个单独的文件中。
视觉元素在.aspx 文件中创建。
●.ascx:的用户控件(也叫做“pagelets”),是作为一种封装了特定功能和行为(这两者要被用在Web应用程序的各种页面上)的Web页面被开发的。
一个用户控件包含了HTML、代码和其他Web 或者用户控件的组合,并在Web服务器上以自己的文件格式保存,其扩展名是*.ascx。
里的缺省配置并不允许Web客户端通过URL来访问这些文件,但是这个网站的其他页面可以集成这些文件里所包含的功能。
●.aspx.cs:Web 窗体页的编程逻辑位于一个单独的类文件中,该文件称作代码隐藏类文件(.aspx.cs)。
●.cs:类模块代码文件。
业务逻辑处理层的代码。
●.asax:Global.asax 文件(也叫做 应用程序文件)是一个可选的文件,该文件包含响应 或HTTP 模块引发的应用程序级别事件的代码。
●.config:Web.config 文件向它们所在的目录和所有子目录提供配置信息。
●.aspx.resx/.resx:资源文件,资源是在逻辑上由应用程序部署的任何非可执行数据。
通过在资源文件中存储数据,无需重新编译整个应用程序即可更改数据。
●.XSD:XML schema的一种.从DTD,XDR发展到XSD●.pdb:PDB(程序数据库)文件保持着调试和项目状态信息,从而可以对程序的调试配置进行增量链接。
●.suo:解决方案用户选项,记录所有将与解决方案建立关联的选项,以便在每次打开时,它都包含您所做的自定义设置。
●.asmx:asmx :文件包含WebService 处理指令,并用作XML Web services 的可寻址入口点51aspx。
c#操作xml文件
![c#操作xml文件](https://img.taocdn.com/s3/m/fd216fb0b1717fd5360cba1aa8114431b90d8ea0.png)
c#操作xml⽂件using System.Xml;//初始化⼀个xml实例XmlDocument xml=new XmlDocument();//导⼊指定xml⽂件xml.Load(path);xml.Load(HttpContext.Current.Server.MapPath("~/file/bookstore.xml"));//指定⼀个节点XmlNode root=xml.SelectSingleNode("/root");//获取节点下所有直接⼦节点XmlNodeList childlist=root.ChildNodes;//判断该节点下是否有⼦节点root.HasChildNodes;//获取同名同级节点集合XmlNodeList nodelist=xml.SelectNodes("/Root/News");//⽣成⼀个新节点XmlElement node=xml.CreateElement("News");//将节点加到指定节点下,作为其⼦节点root.AppendChild(node);//将节点加到指定节点下某个⼦节点前root.InsertBefore(node,root.ChildeNodes[i]);//为指定节点的新建属性并赋值node.SetAttribute("id","11111");//为指定节点添加⼦节点root.AppendChild(node);//获取指定节点的指定属性值string id=node.Attributes["id"].Value;//获取指定节点中的⽂本string content=node.InnerText;//保存XML⽂件string path=Server.MapPath("~/file/bookstore.xml");xml.Save(path);//or use :xml.Save(HttpContext.Current.Server.MapPath("~/file/bookstore.xml"));⼆、具体实例在C#.net中如何操作XML需要添加的命名空间:using System.Xml;定义⼏个公共对象:XmlDocument xmldoc ;XmlNode xmlnode ;XmlElement xmlelem ;1,创建到服务器同名⽬录下的xml⽂件:⽅法⼀:xmldoc = new XmlDocument ( ) ;//加⼊XML的声明段落,<?xml version="1.0" encoding="gb2312"?>XmlDeclaration xmldecl;xmldecl = xmldoc.CreateXmlDeclaration("1.0","gb2312",null);xmldoc.AppendChild ( xmldecl);//加⼊⼀个根元素xmlelem = xmldoc.CreateElement ( "", "Employees", "") ;xmldoc.AppendChild ( xmlelem ) ;//加⼊另外⼀个元素for(int i=1;i<3;i++){XmlNode root=xmldoc.SelectSingleNode("Employees");//查找<Employees> XmlElement xe1=xmldoc.CreateElement("Node");//创建⼀个<Node>节点xe1.SetAttribute("genre","李赞红");//设置该节点genre属性xe1.SetAttribute("ISBN","2-3631-4");//设置该节点ISBN属性XmlElement xesub1=xmldoc.CreateElement("title");xesub1.InnerText="CS从⼊门到精通";//设置⽂本节点xe1.AppendChild(xesub1);//添加到<Node>节点中XmlElement xesub2=xmldoc.CreateElement("author");xesub2.InnerText="候捷";xe1.AppendChild(xesub2);XmlElement xesub3=xmldoc.CreateElement("price");xesub3.InnerText="58.3";xe1.AppendChild(xesub3);root.AppendChild(xe1);//添加到<Employees>节点中}//保存创建好的XML⽂档xmldoc.Save ( Server.MapPath("data.xml") ) ;//////////////////////////////////////////////////////////////////////////////////////结果:在同名⽬录下⽣成了名为data.xml的⽂件,内容如下,<?xml version="1.0"encoding="gb2312"?><Employees><Node genre="李赞红"ISBN="2-3631-4"><title>CS从⼊门到精通</title><author>候捷</author><price>58.3</price></Node><Node genre="李赞红"ISBN="2-3631-4"><title>CS从⼊门到精通</title><author>候捷</author><price>58.3</price></Node></Employees>⽅法⼆:XmlTextWriter xmlWriter;string strFilename = Server.MapPath("data1.xml") ;xmlWriter = new XmlTextWriter(strFilename,Encoding.Default);//创建⼀个xml⽂档 xmlWriter.Formatting = Formatting.Indented;xmlWriter.WriteStartDocument();xmlWriter.WriteStartElement("Employees");xmlWriter.WriteStartElement("Node");xmlWriter.WriteAttributeString("genre","李赞红");xmlWriter.WriteAttributeString("ISBN","2-3631-4");xmlWriter.WriteStartElement("title");xmlWriter.WriteString("CS从⼊门到精通");xmlWriter.WriteEndElement();xmlWriter.WriteStartElement("author");xmlWriter.WriteString("候捷");xmlWriter.WriteEndElement();xmlWriter.WriteStartElement("price");xmlWriter.WriteString("58.3");xmlWriter.WriteEndElement();xmlWriter.WriteEndElement();xmlWriter.Close();//////////////////////////////////////////////////////////////////////////////////////结果:<?xml version="1.0"encoding="gb2312"?><Employees><Node genre="李赞红"ISBN="2-3631-4"><title>CS从⼊门到精通</title><author>候捷</author><price>58.3</price></Node></Employees>2,添加⼀个结点:XmlDocument xmlDoc=new XmlDocument();xmlDoc.Load(Server.MapPath("data.xml"));XmlNode root=xmlDoc.SelectSingleNode("Employees");//查找<Employees>XmlElement xe1=xmlDoc.CreateElement("Node");//创建⼀个<Node>节点xe1.SetAttribute("genre","张三");//设置该节点genre属性xe1.SetAttribute("ISBN","1-1111-1");//设置该节点ISBN属性XmlElement xesub1=xmlDoc.CreateElement("title");xesub1.InnerText="C#⼊门帮助";//设置⽂本节点xe1.AppendChild(xesub1);//添加到<Node>节点中XmlElement xesub2=xmlDoc.CreateElement("author");xesub2.InnerText="⾼⼿";xe1.AppendChild(xesub2);XmlElement xesub3=xmlDoc.CreateElement("price");xesub3.InnerText="158.3";xe1.AppendChild(xesub3);root.AppendChild(xe1);//添加到<Employees>节点中xmlDoc.Save ( Server.MapPath("data.xml") );//////////////////////////////////////////////////////////////////////////////////////结果:在xml原有的内容⾥添加了⼀个结点,内容如下,<?xml version="1.0"encoding="gb2312"?><Employees><Node genre="李赞红"ISBN="2-3631-4"><title>CS从⼊门到精通</title><author>候捷</author><price>58.3</price></Node><Node genre="李赞红"ISBN="2-3631-4"><title>CS从⼊门到精通</title><author>候捷</author><price>58.3</price></Node><Node genre="张三"ISBN="1-1111-1"><title>C#⼊门帮助</title><author>⾼⼿</author><price>158.3</price></Node></Employees>3,修改结点的值(属性和⼦结点):XmlDocument xmlDoc=new XmlDocument();xmlDoc.Load( Server.MapPath("data.xml") );XmlNodeList nodeList=xmlDoc.SelectSingleNode("Employees").ChildNodes;//获取Employees节点的所有⼦节点foreach(XmlNode xn in nodeList)//遍历所有⼦节点{XmlElement xe=(XmlElement)xn;//将⼦节点类型转换为XmlElement类型if(xe.GetAttribute("genre")=="张三")//如果genre属性值为“张三”{xe.SetAttribute("genre","update张三");//则修改该属性为“update张三”XmlNodeList nls=xe.ChildNodes;//继续获取xe⼦节点的所有⼦节点foreach(XmlNode xn1 in nls)//遍历{XmlElement xe2=(XmlElement)xn1;//转换类型if(=="author")//如果找到{xe2.InnerText="亚胜";//则修改}}}}xmlDoc.Save( Server.MapPath("data.xml") );//保存。
vc6.0写xml案例
![vc6.0写xml案例](https://img.taocdn.com/s3/m/26fe0449b42acfc789eb172ded630b1c59ee9bd2.png)
vc6.0写xml案例在VC6.0中编写XML的案例,可以通过使用MSXML库来实现。
下面我将从多个角度来介绍如何在VC6.0中编写一个简单的XML案例。
1. 包含头文件和初始化。
首先,在VC6.0中创建一个新的Win32控制台应用程序项目。
然后在代码中包含MSXML库的头文件,可以使用以下代码:c.#include <msxml2.h>。
接着,需要初始化COM组件,可以使用以下代码:c.CoInitialize(NULL);2. 创建XML文档。
接下来,我们可以创建一个XML文档对象并添加元素和属性。
以下是一个简单的示例代码:c.IXMLDOMDocument pXMLDom = NULL;HRESULT hr = CoCreateInstance(__uuidof(DOMDocument), NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument,(void)&pXMLDom);if (SUCCEEDED(hr))。
{。
IXMLDOMElement pRoot = NULL;pXMLDom->createElement(L"Root", &pRoot);pXMLDom->appendChild(pRoot, NULL);IXMLDOMElement pChild = NULL;pXMLDom->createElement(L"Child", &pChild);pRoot->appendChild(pChild, NULL);pChild->setAttribute(L"Attribute",_variant_t(L"Value"));}。
3. 保存和释放资源。
在完成XML文档的创建后,我们需要保存XML文档并释放资源。
C中对XML文件的操作
![C中对XML文件的操作](https://img.taocdn.com/s3/m/3b19871953ea551810a6f524ccbff121dd36c54e.png)
Xml作为一个非常重要的纯文本格式已经进入了编程的很多领域,作为一个面向应用层面的c#也一样在很多领域离不开Xm l。
但是,c#在很多方面对X ml做了写封装,以至于很多操作Xml的代码,都不需要手动去写。
例如,c#写WebSer vice这种需要大量操作Xml的服务,除了极其个别的情况下,基本看不到任何操作Xml的代码。
这是c#的一个优势,但是,最近发现正是这样一些c#的优势,导致了新一代c#程序员的能力退化。
因为90%的情况下,不需要手动操作Xml,所以,年轻的c#程序员也觉得没必要为了这10%的情况,而去学如何手工读写Xml。
真不知道,ms 提供了这么简便的工具,是ms做的善事还是作的孽。
好吧,废话就不说了,转入主题。
1.如何用XmlDom的方式读取XmlXml Dom方式是最原始的一种操作Xml的途径,从.net Framewo rk 1.0开始就开始支持Dom方式。
1.1如何以Dom方式加载Xm l要读取Xml首先要加载Xm l,加载的方式有两种,一种是从流或类似的Read er加载,例如:当然还可以从字符串加载:1.1读取无nam espace的XmlXml已经准备好了,下面就开始读取这个Xml。
现在希望读取d ata节下面的所有ite m中的tex t,那么就可以:看看运行结果:但是,这样写的问题有很多,例如在data节点中有非i tem的节点,这样访问,也就被无差别的把非item项也写出来了。
例如把如果数据改成这样:这样,在data节里面,除了4个ite m,还有一个oth er,这个other是不需要的,必须被排除掉,如果直接用第一中Child Nodes去访问的话,会得到这样的结果:显然“!@#”也被选择出来了,这可不是我们所期望的,所以,改用XPath的方式访问:其运行结果为:很好的othe r项排除在需要的节点外,这才是我们真正想要的结果:)1.2读取有nam espace的Xml和c#一样Xml也有namesp ace,并且names pace在X ml中的作用巨大,也许你并未感受到names pace的作用,但是,你可能已经不得不面对那些有namesp ace的Xm l了。
c++读取处理xml文件的实例
![c++读取处理xml文件的实例](https://img.taocdn.com/s3/m/c256917f86c24028915f804d2b160b4e777f8148.png)
c++读取处理xml文件的实例C++ 作为一种强大的编程语言,可以用来读取和处理 XML 文件。
XML(可扩展标记语言)是一种常见的文本格式,用于存储和传输数据。
在 C++ 中,你可以使用许多库和工具来读取和处理 XML 文件,其中包括 Xerces-C++、TinyXML、RapidXML 等。
下面我将以使用RapidXML 库为例,展示一个简单的 C++ 代码来读取和处理 XML 文件。
首先,你需要在你的 C++ 项目中包含 RapidXML 库的头文件,并链接相应的库文件。
接下来,你可以使用 RapidXML 的 API 来打开 XML 文件、解析其中的内容并对其进行操作。
下面是一个简单的示例代码:cpp.#include <iostream>。
#include <fstream>。
#include "rapidxml.hpp"int main() {。
// 读取 XML 文件。
std::ifstream file("example.xml");std::stringxml_content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());// 解析 XML 内容。
rapidxml::xml_document<> doc;doc.parse<0>(&xml_content[0]);// 获取根节点。
rapidxml::xml_node<> root_node = doc.first_node();// 遍历子节点并处理数据。
for (rapidxml::xml_node<> node = root_node->first_node("item"); node; node = node->next_sibling("item")) {。
vc++使用MFC操作EXCEL文件
![vc++使用MFC操作EXCEL文件](https://img.taocdn.com/s3/m/cbd0b4ea172ded630b1cb61d.png)
使用MFC操作EXCEL文件本文档适用于:•Microsoft Foundation Classes (MFC), Microsoft Visual C++, 32-bit Editions, version 6.0 以上•Microsoft OLE 库第一步:建立一个自动化工程1.启动VC 6.0,打开新建对话框,新建一个MFC AppWizard(exe)工程,这里工程明设置为TestExcel。
2.进入MFC 应用程序向导,选择基本对话框,直接点击完成,工程文件结构如下图:3.打开MFC ClassWizard窗口(查看—>建立类向导),选择Automation,单击AddClass按钮,选择From a type library...,弹出文件选择对话框,之后定位到Microsoft Office的安装目录(通常为C:\Program Files\Microsoft Office\Office),选择EXCEL9.OLB注意,确定后,弹出Confirm Classes窗口,选择列表中的所有类,单击OK按钮。
注意文件名EXCEL9.OLB,因安装的Office版本不同而有所差异,EXCEL9.OLB对应的是Microsoft Office 2000,微软命名方式为Excel+数字的形式,Office版本越高,数字越大。
4.返回编辑器,查看工程文件,可发现多了EXCEL9.H及EXCEL9.CPP两个文件。
5.打开stdafx.h头文件确保包含如下头文件:#include <afxdisp.h>#include "excel9.h"6.打开TestExcel.cpp文件,修改CTestExcelApp::InitInstance(),加入如下代码:BOOL CTestExcelApp::InitInstance(){if( !AfxOleInit() ){AfxMessageBox("初始化Ole出错!");return FALSE;}AfxEnableControlContainer();............return FALSE;}为保证编译时不产生重复定义错误,打开excel9.h文件,在文件开始位置加入如下代码:#if !defined _HEAD_FILE_EXCEL9_#define _HEAD_FILE_EXCEL9_相应的,在文件末尾加入:#endif到此,OLE自动化工程建立完成。
MFC如何读取XML
![MFC如何读取XML](https://img.taocdn.com/s3/m/92fd242cbdd126fff705cc1755270722192e59d1.png)
MFC如何读取XML <?xml version="1.0" encoding="utf-8"?><Cases><case><No>001</No><CopyFile src="C:\test.txt" dest="D:\test.txt"></CopyFile></case><case><No>002</No><DelFile>C:\test.txt</DelFile></case></Cases>我们⽤MFC来读取上述xml,代码如下:void CXXXDlg::ReadXml(CString strXmlPath){MSXML2::IXMLDOMDocumentPtr pDoc;::CoInitialize(NULL);HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));if (!SUCCEEDED(hr)){MessageBox(_T("创建DOMDocument对象失败。
\n请检查运⾏环境"), _T("错误"), MB_ICONERROR);return;}// 读取xmlpDoc->put_async(VARIANT_FALSE);VARIANT_BOOL bhr = pDoc->load((_variant_t)strXmlPath);if (bhr != VARIANT_TRUE) {MessageBox(_T("⽆法正确读取xml⽂件"), _T("错误"), MB_ICONERROR);return;}// 根节点取得MSXML2::IXMLDOMElementPtr root = pDoc->documentElement;// 取得根节点的名字_variant_t strRootName = root->nodeName;_bstr_t wstrRootName(strRootName.bstrVal);MSXML2::IXMLDOMNodeListPtr nodeList = root->GetchildNodes();//cases// 解析cases的⼦节点ReadCases(nodeList);}void CXXXDlg::ReadCases(MSXML2::IXMLDOMNodeListPtr nodeList){int ilength = nodeList->Getlength();for (int nodeCount = 0; nodeCount < ilength; nodeCount++) {MSXML2::IXMLDOMNodePtr nodePtr = nodeList->nextNode();_variant_t strNodeName = nodePtr->GetnodeName();_variant_t strNodeValue = nodePtr->GetnodeValue();// 读取case节点下的⼦节点ReadCase(nodePtr->GetchildNodes());}}void CXXXDlg::ReadCase(MSXML2::IXMLDOMNodeListPtr nodeList){CString strLogInfo;strLogInfo.Empty();CString strNo; // case编号CString strSrcFile; // 源⽂件CString strDestFile; // ⽬标⽂件for (int nodeCount = 0; nodeCount < nodeList->Getlength(); nodeCount++){MSXML2::IXMLDOMNodePtr nodePtr = nodeList->nextNode();_variant_t strCaseNodeName = nodePtr->GetnodeName();_variant_t strCaseNodeValue = nodePtr->Gettext();BSTR bStrTemp = strCaseNodeName.bstrVal;CString strTemp = CString(bStrTemp);SysFreeString(bStrTemp);CString strNodeName = strTemp;// 节点的值,如何取得?if (0 == pareNoCase(_T("NO"))){strNo = (BSTR)strCaseNodeValue.pbstrVal;// 取得的值可以打印出来printf(strNo);}// 节点有属性值,该怎么处理?else if (0 == pareNoCase(_T("CopyFile"))){strSrcFile.Empty();strDestFile.Empty();// 取得节点的属性值MSXML2::IXMLDOMNamedNodeMapPtr pDOMAttrList= nodePtr->Getattributes();for (int j = 0; j < pDOMAttrList->Getlength(); j++){MSXML2::IXMLDOMNodePtr pDOMAttr= pDOMAttrList->Getitem(j);// 取得源⽂件路径if (CompareNoCase((char*)pDOMAttr->GetnodeName(), _T("src"))){strSrcFile = pDOMAttr->GetnodeTypedValue();// 取得⽬标⽂件路径} else if (CompareNoCase((char*)pDOMAttr->GetnodeName(), _T("dest"))){strDestFile =pDOMAttr->GetnodeTypedValue();}printf("strSrcFile = %s\n", strSrcFile);printf("strDestFile = %s\n", strDestFile );}else if (0 == pareNoCase(_T("DelFile"))){strDestFile.Empty();strDestFile = CString((BSTR)strCaseNodeValue.pbstrVal);printf("strDestFile = %s\n", strDestFile );}}}为了能够让MFC认识MSXML2,我们需要引⼊相应的dll,代码如下;#import "msxml4.dll"。
VC++6.0控件使用方法大全
![VC++6.0控件使用方法大全](https://img.taocdn.com/s3/m/2c6e700279563c1ec5da71db.png)
使用Windows标准控件我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对话框或其它窗口中充当与用户交互的元素。
在Visual C++中,可以使用的控件分成三类:(1) Windows标准控件Windows标准控件由Windows操作系统提供,在Windows 95中还提供了一些新增的控件。
所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。
Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。
表6.1 Windows标准控件控件 MFC类 描述动画 CAnimateCtrl 显示连续的AVI视频剪辑按钮 CButton 用来产生某种行为的按钮,以及复选框、单选钮和组框组合框 CComboBox 编辑框和列表框的组合编辑框 CEdit 用于键入文本标题头 CHeaderCtrl 位于某一行文本之上的按钮,可用来控制显示文件的宽度热键 CHotKeyCtrl 用于通过按下某一组合键来很快的执行某些常用的操作图象列表 CImageList 一系列图象(典型情况下是一系列图标或位图)的集合。
图象列表本身不是一种控件,它常常是和其它控件一起工作,为其它控件提供所用的图象列表列表 CListCtrl 显示文本及其图标列表的窗口列表框 CListBox 包括一系列字符串的列表进度 CProgressCtrl 用于在一较长操作中提示用户所完成的进度多格式文本编辑 CRichEditCtrl 提供可设置字符和段落格式的文本编辑的窗口滚动条 CScrollBar 为对话框提供控件形式的滚动条滑块 CSliderCtrl 包括一个有可选标记的滑块的窗口旋转按钮 CSpinButtonCtrl 提供一对可用于增减某个值的箭头静态文本 CStatic 常用于为其它控件提供标签状态条 CStatusBarCtrl 用于显示状态信息的窗口,同MFC类CStatusBar类似续表6.1 控件 MFC类 描述选项卡 CTabCtrl 在选项卡对话框或属性页中提供具有类似笔记本中使用的分隔标签的外观的选项卡工具条 CToolBarCtrl 具有一系列命令生成按钮的窗口,同MFC类CToolBar类似工具提示 CToolTipCtrl 一个小的弹出式窗口,用于提供对工具条按钮或其它控件功能的简单描述树 CTreeCtrl 用于显示一系列的项的继承结构前面提到过,在MFC中,类CWnd是所有窗口类的基类,很自然的,它也是所有控件类的基类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC++中操作XML(MFC、SDK)XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini。
VC++里操作XML有两个库可以用:MSXML和XmlLite。
MSXML又细分了两种接口:DOM和SAX2。
XP没自带有XmlLite,只自带有2.x、3.x版的MSXML,不支持SAX2(需要MSXML 4.0以上),所以优先使用DOM。
DOM是以COM形式提供的,VC++里调用DOM可以分3种方法:1、MFC里用CComPtr调用2、SDK里直接调用DOM接口3、SDK里用智能指针调用这3种方法本质上是一样的,区别只不过在于需要编码的多少而已,用CComPtr可以极大的简化代码,下面是几个例子。
例子stocks.xml:<?xml version="1.0"encoding="utf-8"?><root><node1>text1</node1><node2><childnode1attrib1="value1"attrib2="value2"/><childnode2attrib1="value1"attrib2="value2">childtext1</childnode2></node2></root>这个例子应该包含了XML最常见的特征了吧?MFCMFC里可以直接使用DOM,不需要手动添加额外的头文件,只需要在CWinApp::InitInstance()里调用CoInitialize(NULL)初始化COM,在CWinApp::ExitInstance里调用CoUninitialize()释放COM就行了。
//读取XMLCComPtr<IXMLDOMDocument> spDoc;//DOMspDoc.CoCreateInstance(CLSID_DOMDocument);VARIANT_BOOL vb;spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb);//加载XML文件CComPtr<IXMLDOMElement> spRootEle;spDoc->get_documentElement(&spRootEle);//根节点CComPtr<IXMLDOMNodeList> spNodeList;spRootEle->get_childNodes(&spNodeList);//子节点列表long nLen;spNodeList->get_length(&nLen);//子节点数for(long i =0; i != nLen;++i)//遍历子节点{CComPtr<IXMLDOMNode> spNode;spNodeList->get_item(i, &spNode);ProcessNode(spNode);//节点处理函数}//写入XMLCComPtr<IXMLDOMNode> spNode;spRootEle->selectSingleNode(OLESTR("/root/node1"), &spNode);spNode->put_text(OLESTR("newText"));//写入textspRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode); spNode->put_nodeValue(CComVariant(OLESTR("newValue")));//写入valueCComPtr<IXMLDOMNode> spNewNode;spDoc->createNode(CComVariant(NODE_ELEMENT), OLESTR("childnode3"), OLESTR(""), &spNewNode);//创建新节点spRootEle->selectSingleNode(OLESTR("/root/node2"), &spNode);spNode->appendChild(spNewNode, &spNewNode);//将新节点加为node2的子节点spNewNode->put_text(OLESTR("childtext2"));//写入新节点textCComQIPtr<IXMLDOMElement> spEle = spNewNode;//注意这里使用CComQIPtrspEle->setAttribute(OLESTR("attrib1"), CComVariant(OLESTR("value1")));//给新节点添加属性spDoc->save(CComVariant(OLESTR("stocks.xml")));//节点处理函数void ProcessNode(CComPtr<IXMLDOMNode>& spNode){CComBSTR bsNodeName;spNode->get_nodeName(&bsNodeName);//节点名AfxMessageBox(COLE2CT(bsNodeName));CComVariant varVal;spNode->get_nodeValue(&varVal);//节点值AfxMessageBox(COLE2CT(varVal.bstrVal));DOMNodeType eNodeType;spNode->get_nodeType(&eNodeType);if(eNodeType == NODE_ELEMENT)//只有NODE_ELEMENT类型才能包含有属性和子节点{//递归遍历节点属性CComPtr<IXMLDOMNamedNodeMap> spNameNodeMap;spNode->get_attributes(&spNameNodeMap);long nLength;spNameNodeMap->get_length(&nLength);for(long i =0; i != nLength;++i){CComPtr<IXMLDOMNode> spNodeAttrib;//注意属性也是一个IXMLDOMNode spNameNodeMap->get_item(i, &spNodeAttrib);ProcessNode(spNodeAttrib);}//递归遍历子节点CComPtr<IXMLDOMNodeList> spNodeList;spNode->get_childNodes(&spNodeList);spNodeList->get_length(&nLength);for(long i =0; i != nLength;++i){CComPtr<IXMLDOMNode> spChildNode;spNodeList->get_item(i, &spChildNode);ProcessNode(spChildNode);}}}对于<tag>text</tag>这样的节点,get_nodeValue会得到空,要得到"text"的话可以遍历子节点(只有一个子节点,它的nodeName为"#text",nodeType为NODE_TEXT,nodeValue就是"text");也可以用get_text 直接得到"text",但是对于这样的节点<tag>text<childtag>childtext</childtag></tag>,get_text会同时得到"text"和"childtext",不过这样的节点应该是不允许的。
DOM里使用的字符串(BSTR)都是OLESTR类型,默认情况下OLESTR是Unicode字符,MFC里可以用COLE2CT把LPCOLESTR转换为LPCTSTR。
对于自己定义的XML,大多数时候不需要遍历,可以通过调用selectNodes、selectSingleNode指定XPath 直接读取某个节点或属性:CComPtr<IXMLDOMDocument> spDoc;//DOMspDoc.CoCreateInstance(CLSID_DOMDocument);VARIANT_BOOL vb;spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb);//加载XML文件CComPtr<IXMLDOMElement> spRootEle;spDoc->get_documentElement(&spRootEle);//根节点CComPtr<IXMLDOMNodeList> spNodeList;CComPtr<IXMLDOMNode> spNode;spRootEle->selectNodes(OLESTR("/root/node2/*"), &spNodeList);//得到node2下的所有子节点spRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode);//得到childnode1的attrib1属性XPath的语法可以参考XML文档或MSDN。