VC 使用msxml6.dll动态链接库中的函数读写XML文件
VC 使用msxml6.dll动态链接库中的函数读写XML文件
目录
1 引言
2 .dll使用方法
3 常用函数总结
4 实例应用
5 运行效果预览
6 补充说明
7 不足之处
8 更新
引言:
在C:\WINDOWS\system32\下有msxml3.dll 和 msxml6.dll两个动态链接库可以提供操作XML文件的函数。这两个只是版本不同,使用其一即可。
.dll使用方法:
#import "C:\\WINDOWS\\system32\\msxml6.dll"
using namespace MSXML2;
常用函数总结:
- a.创建xml文档对象
- MSXML2::IXMLDOMDocumentPtr pDoc; //声明xml文档指针
- HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30)); //实例化xml文档对象
- delete pDoc;
- b.创建"Element"、添加"Element"到xml文档对象中
- MSXML2::IXMLDOMElementPtr xmlRoot; //声明"Element"指针
- pDoc->raw_createElement( (_bstr_t)(char*)"China", &xmlRoot); //创建"Element"
- pDoc->raw_appendChild(xmlRoot, NULL); //添加"Element"到xml文档对象中
- c.为"Element"添加属性及其属性值
- MSXML2::IXMLDOMElementPtr pElemNode;
- pDoc->raw_createElement( (_bstr_t)(char*)"City", &childNode);
- pElemNode->setAttribute("population","7000"); //1:属性名 2:属性值
- d.元素之间的Text操作
- MSXML2::IXMLDOMElementPtr pElemNode; //声明一个元素(Element)指针
- pElemNode->Puttext("shanghai"); //设置Element之间的Text
- CString strElemText = (char*)(_bstr_t)pElemNode->Gettext(); //获取Element之间的Text
- e.创建、保存XML文档
- pDoc->save(".\\test.xml"); //创建、保存并关闭xml文档
- f.加载xml文档
- MSXML2::IXMLDOMDocumentPtr pDoc;
- HRESULT loadrs = pDoc->load(".\\test.xml"); //加载xml文档
- g.查询"Element"
- //查询到一个或多个节点,返回第一个节点;如果没有查询的任何节点返回 Nothing
- pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//City")); //获取元素的信息
- h.与xml一起常用的容器
- //IXMLDOMNamedNodeMap 是一个结点容器,允许通过name或index访问
- //这个容器是通常用于容纳属性
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- //IXMLDOMNodeList 是一个动态容器,也就是说:添加、删除结点
- //以及改变结点,都会立即更新容器
- MSXML2::IXMLDOMNodeListPtr nodeList = NULL;
- //结点指针
- MSXML2::IXMLDOMNodePtr pAttrItem = NULL;
- j.容器的使用
- pElemNode->get_attributes(&pAttrs); //获取pElemNode指向的元素的属性集
- pElemNode->get_childNodes(&nodeList); //获取子节点
- long nCount, iCount;
- //IXMLDOMNamedNodeMapPtr->get_length(long* ) 返回容器中保存属性的个数
- pAttrs->get_length(&nCount); //获取结点属性个数 2
- //IXMLDOMNodeListPtr->get_length(long* ) 返回容器中保存结点的个数
- nodeList->get_length(&iCount); //获取子结点个数 1
- for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中
- {
- CString strElemText = (char*)(_bstr_t)pElemNode->Gettext(); //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本
- m_list.InsertItem(i,strElemText); //1:行索引 2:待添加的字串
- for(int j = 0; j < nCount; j++ )
- {
- pAttrs->get_item(j,&pAttrItem); //获取结点信息-结点
- //CString strAttrName = (char*)(_bstr_t)pAttrItem->nodeName; //当前元素(Element)指定属性的名称
- CString strAttrVale = (char*)(_bstr_t)pAttrItem->nodeTypedValue; //当前元素指定属性的值
- m_list.SetItemText(i,j+1,strAttrVale); //1:行索引 2:列索引 3:待添加的字串
- //m_list.SetItemText(i,2,strAttrName);
- }
- }
- k.重要的函数
- <1>获取子元素
- IXMLDOMNodeListPtr nodelist=NULL;
- pElemNode->get_childNodes(&nodeList); //两个函数是等效的
- nodelist = pElemNode->GetchildNodes();
- 保存pElementNode元素下的所有指向子元素的指针。
- <book category="children">
- <title lang="en">Harry Potter</title>
- <author>J K. Rowling</author>
- <year>2005</year>
- <price>29.99</price>
- </book>
- 如pElement指向 <book> </book>,则<title>、<author>、<year>、<price>都是pElement的子结点(或称为子元素)
- <2>返回nodeList容器中当前结点(应该是一个游标指针来实现的)的下一个结点。
- nodeList->nextNode()
- 例子:
- pElemNode = pDoc->selectSingleNode("//China"); //获取元素的信息
- MSXML2::IXMLDOMNodeListPtr nodeList = NULL; //list容器
- pElemNode->get_childNodes(&nodeList); //获取子节点
- pCurNode = nodeList->nextNode();
- <3>pCurNode->GetnextSibling()
- Retrieves the next sibling(元素处于同一树层级中) of this node in the parent's child list.如果无此节点,则返回 null。
- 备注:目前用法没有验证。
- 可配合下面两个函数使用:
- get_firstChild Retrieves the first child of this node.
- get_lastChild Retrieves the last child of this node.
- <4>获取元素的属性值
- <City population="12000" name="Wuhan"> </City>
- m_pCurNode指向<City> </City>这个元素
- CString varVal = m_pCurNode->getAttribute("population"); //varVal = "12000"
- ------特别注意--------
- <China>
- <City population="7000" area="2000">
- <Area> QingShan </Area>
- </City>
- </China>
- 如果pElemNode当前指向<City> </City>这个节点,
- 那么
- CString strElemText = (char*)(_bstr_t)pElemNode->Gettext();
- strElemText的值就是“QingShan”
实例应用
应用1:
- 测试用的xml文件-- test.xml
- <China>
- <City population="7000" area="2000">shanghai</City>
- <City population="39999" area="3322">beijing</City>
- <City population="5000" area="40000">Wuhan</City>
- </China>
- #import "C:\\WINDOWS\\system32\\msxml6.dll"
- using namespace MSXML2;
- //创建xml文件
- void COperateXMLDlg::OnBtnCreate()
- {
- // TODO: Add your control notification handler code here
- ::CoInitialize(NULL); //初始化COM
- MSXML2::IXMLDOMDocumentPtr pDoc;
- MSXML2::IXMLDOMElementPtr xmlRoot;
- HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));
- if(!SUCCEEDED(hr))
- {
- MessageBox("XML文件创建失败");
- return ;
- }
- pDoc->raw_createElement( (_bstr_t)(char*)"China", &xmlRoot);
- pDoc->raw_appendChild(xmlRoot, NULL);
- MSXML2::IXMLDOMElementPtr pElemNode;
- pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);
- pElemNode->Puttext("shanghai");
- pElemNode->setAttribute("population","7000");
- pElemNode->setAttribute("area","2000");
- xmlRoot->appendChild(pElemNode);
- pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);
- pElemNode->Puttext("beijing");
- pElemNode->setAttribute("population","39999");
- pElemNode->setAttribute("area","3322");
- xmlRoot->appendChild(pElemNode);
- pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);
- pElemNode->Puttext("Wuhan");
- pElemNode->setAttribute("population","5000");
- pElemNode->setAttribute("area","40000");
- xmlRoot->appendChild(pElemNode);
- pDoc->save(".\\test.xml");
- //如何释放pDoc占有的内存
- ::CoUninitialize(); //卸载COM
- }
- //读取xml文件
- void COperateXMLDlg::OnBtnGetXML()
- {
- // TODO: Add your control notification handler code here
- ::CoInitialize(NULL); //初始化COM
- m_list.DeleteAllItems(); //m_list是ListControl控件绑定的一个Value类型的变量
- MSXML2::IXMLDOMDocumentPtr pDoc; //创建一个xml文档指针
- HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30)); //实例化文档指针
- if(!SUCCEEDED(hr))
- {
- MessageBox("加载XML错误");
- return ;
- }
- VARIANT_BOOL loadrs = pDoc->load(".\\test.xml"); //加载xml文档
- if( -1 != loadrs ) //查看load函数的定义(msxml3.tli)发现返回类型是VARIANT_BOOL,-1 == TRUE、0 == FALSE
- MessageBox("加载XML错误");
- MSXML2::IXMLDOMElementPtr pElemNode; //声明一个元素(Element)指针
- // 在树中查找名为City的节点," // "表示在任意一层查找
- //selectSingleNode方法如果查询到一个或多个节点,返回第一个节点;如果没有查询的任何节点返回 Nothing
- //SelectNodes("//City")返回一个NodeList对象,可能包含多个节点
- pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//China")); //获取元素的信息
- //MSXML2::DOMNodeType nodeType; //结点类型
- //childNode->get_nodeType(&nodeType);
- //IXMLDOMNamedNodeMap 是一个结点容器,允许通过name或index访问
- //这个容器是通常用于容纳属性
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- //IXMLDOMNodeList 是一个动态容器,也就是说:添加、删除结点
- //以及改变结点,都会立即更新容器
- MSXML2::IXMLDOMNodeListPtr nodeList = NULL;
- //结点指针
- MSXML2::IXMLDOMNodePtr pAttrItem = NULL;
- //pElemNode->get_attributes(&pAttrs); //获取pElemNode指向的元素的属性集
- pElemNode->get_childNodes(&nodeList); //获取子节点
- long nCount, iCount;
- MSXML2::IXMLDOMElementPtr pCurNode;
- //IXMLDOMNamedNodeMapPtr->get_length(long* ) 返回容器中保存属性的个数
- //pAttrs->get_length(&nCount); //获取结点属性个数 2
- //IXMLDOMNodeListPtr->get_length(long* ) 返回容器中保存结点的个数
- nodeList->get_length(&iCount); //获取子结点(此处指"China"元素下的子元素"City")个数 2
- for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中
- {
- pCurNode = nodeList->nextNode();
- CString strPoupula = pCurNode->getAttribute("population");
- CString strArea= pCurNode->getAttribute("area");
- CString strElemText = (char*)(_bstr_t)pCurNode->Gettext(); //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本
- m_list.InsertItem(i,strElemText); //1:行索引 2:待添加的字串
- m_list.SetItemText(i,1,strPoupula); //1:行索引 2:列索引 3:待添加的字串
- m_list.SetItemText(i,2,strArea);
- }
- ::CoUninitialize(); //卸载COM
- }
运行效果预览:
实例下载链接,上传到CSDN的资源库中,0分资源,支持VC6和VS2010IDE。下载此工程实例--VC6/VS2010
应用2:
- <China>
- <Provious name="Hubei">
- <City population="1" area="100">YiChang</City>
- <City population="2" area="40000">Wuhan</City>
- </Provious>
- <Provious name="HeBei">
- <City population="39999" area="3322">beijing</City>
- <City population="39999" area="3322">QingDao</City>
- </Provious>
- <Provious name="JiangSu">
- <City population="7000" area="2000">shanghai</City>
- </Provious>
- </China>
- void COperateXMLDlg::OnBtnGetXML()
- {
- // TODO: Add your control notification handler code here
- ::CoInitialize(NULL); //初始化COM
- m_list.DeleteAllItems();
- MSXML2::IXMLDOMDocumentPtr pDoc; //创建一个xml文档指针
- HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30)); //实例化文档指针
- if(!SUCCEEDED(hr))
- {
- MessageBox("加载XML错误");
- return ;
- }
- VARIANT_BOOL loadrs = pDoc->load(".\\test.xml"); //加载xml文档
- if( -1 != loadrs ) //查看load函数的定义(msxml3.tli)发现返回类型是VARIANT_BOOL,-1 == TRUE、0 == FALSE
- MessageBox("加载XML错误");
- MSXML2::IXMLDOMElementPtr pElemNode; //声明一个元素(Element)指针
- // 在树中查找名为City的节点," // "表示在任意一层查找
- pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//China")); //获取元素的信息
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- MSXML2::IXMLDOMNodeListPtr nodeList = NULL;
- MSXML2::IXMLDOMNodePtr pAttrItem = NULL;
- pElemNode->get_childNodes(&nodeList); //获取子节点
- long nCount, iCount,index=0;
- MSXML2::IXMLDOMElementPtr pCurNode,pChildCurNode;
- nodeList->get_length(&iCount);
- for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中
- {
- pCurNode = nodeList->nextNode();
- MSXML2::IXMLDOMNodeListPtr ChildnodeList = NULL;
- pCurNode->get_childNodes(&ChildnodeList);
- ChildnodeList->get_length(&nCount);
- for(int j=0; j < nCount; j++ )
- {
- pChildCurNode = ChildnodeList->nextNode();
- CString strPoupula = pChildCurNode->getAttribute("population");
- CString strArea= pChildCurNode->getAttribute("area");
- CString strElemText = (char*)(_bstr_t)pChildCurNode->Gettext(); //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本
- m_list.InsertItem(index,strElemText); //1:行索引 2:待添加的字串
- m_list.SetItemText(index,1,strPoupula);
- m_list.SetItemText(index,2,strArea);
- index++;
- }
- }
- ::CoUninitialize(); //卸载COM
- }
补充说明:
项目中导入msxml3.dll或是msxml6.dll经过编译后会项目目录下生成两个文件msxml3.tlh和msxml3.tli(msxml6.tlh和msxml6.tli),绝大部分操作xml文件的函数都定义在msxml3.tli中,可在工程中选中函数名称右键查看其定义便会一目了然。
不足之处:
目前还没在Unicode字符集下成功的读取过,只要xml文件中包含Unicode字符,加载函数load("test.xml")就会返回加载失败的值。目前还没有找到原因。留此待已解决,Mark20131228.
问题解决了,在xml文件中少写了文件头“ <?xml version="1.0" encoding="gb2312"?> ”造成上面的load函数加载失败。Mark:20131231
更新:
20140311更 -- 解决每次写入信息到xml文件都是全覆盖模式,如此xml文件头<?xml version="1.0" encoding="gb2312"?>也会被覆盖掉,这样会引起“不足之处”里面提到的编码问题。找了很久没有找专门供写入xml文件头<?xml version="1.0" encoding="gb2312"?>的函数,于是自己动手写了一函数解决这个问题。
解决方法是:先将xml文件中原有的信息(此时不包括xml文件头)读取出来保存到一个字符串变量中,接着将<?xml version="1.0" encoding="gb2312"?>和字符串变量中的信息串接起来,然后再写入到xml文件中。代码如下
- BOOL AddXMLHeadString()
- {
- //由于必须从文件最开头添加字符会覆盖掉原来的字符,所以采用下面的方法解决这个问题
- //先把原始文件读取出来,然后加上xml的文件头字符串,再写回去。
- //char readBuf[]
- CString fileName(_T(".\\test.xml") );
- CStdioFile myfile;
- CFileException fileExcp;
- BOOL bRet = myfile.Open(fileName,CFile::typeText|CFile::modeReadWrite,&fileExcp);
- if( bRet )
- {
- /*一个稀奇事:如果1 、2 部分调换顺序就会使myfile.Read读取文件内容异常,但是两者的顺序是无关紧要的*/
- //1.读取原有文件的内容
- UINT fileLen = myfile.GetLength();
- char * readBuf = new char[fileLen];
- myfile.Read(readBuf,fileLen);
- //2.如果已经有了XML文件头就不添加
- CString strXMLHeader;
- myfile.ReadString(strXMLHeader);
- CString xmlHeader = _T("<?xml version=\"1.0\" encoding=\"gb2312\"?>");
- if( xmlHeader== strXMLHeader )
- return TRUE;
- myfile.Close();
- //3.合成完整的xml文件
- CStdioFile newFile;
- BOOL bRetNewFile = newFile.Open(fileName,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite,&fileExcp);
- if( bRetNewFile )
- {
- newFile.Seek(0,CFile::end);
- newFile.WriteString(_T("<?xml version=\"1.0\" encoding=\"gb2312\"?>\n"));
- newFile.Seek(0,CFile::end);
- newFile.Write(readBuf,fileLen);
- newFile.Seek(-1,CFile::end); //在文件末尾莫名其妙的多了一个‘?’,所以用了‘\n’将这个问号覆盖了,不然读取XML时会出错
- newFile.WriteString(_T("\n"));
- }
- }
- char *errinfo = new char [255];
- fileExcp.GetErrorMessage(errinfo,255);
- delete[] errinfo;
- return bRet;
- }
http://blog.csdn.net/qq2399431200/article/details/17583171
http://z.download.csdn.net/detail/qq2399431200/7022299
VC 使用msxml6.dll动态链接库中的函数读写XML文件的更多相关文章
- C# DumpBin使用 查看反射C++ dll 动态链接库中的函数
DumpBin是Microsoft提供的一个用于查看.exe..dll文件信息的工具,其位于: C:\Program Files (x86)\Microsoft Visual Studio 10.0\ ...
- 在DLL动态链接库中封装VCL的MDI子窗体
在DLL动态链接库中封装VCL的MDI子窗体不多说了,看代码就应该明白了,曾经我遇到的问题,现在放出来大家共享! 这里是工程文件的部分: 在DLL中封装MDI子窗体需要重写DLL入口函数,具体代码如下 ...
- 从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法
原文:从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法 主程序 为 Main_Test.exe 被加载的DLL 为 Load_Test.dll 此DLL 中 有一个 文件夹Re ...
- java中采用dom4j解析xml文件
一.前言 在最近的开发中用到了dom4j来解析xml文件,以前听说过来解析xml文件的几种标准方式:但是从来的没有应用过来,所以可以在google中搜索dmo4j解析xml文件的方式,学习一下dom4 ...
- 在C#中创建和读取XML文件
1.创建简单的XML文件 为了便于测试,我们首先创建控制台应用程序,项目命名为CreateXml,Program.cs代码如下: 这样会在C盘根目录下创建data2.xml文件,文件内容为 using ...
- Spring中加载ApplicationContext.xml文件的方式
Spring中加载ApplicationContext.xml文件的方式 原文:http://blog.csdn.net/snowjlz/article/details/8158560 1.利用Cla ...
- C#程序中:如何删除xml文件中的节点、元素。
C#中动态的清理xml文件中的垃圾信息是程序员必会的哦.这就像数据库一样,不会清理数据怎么可以呢?其实xml文件就可以用作一个小的数据库,存储一些简单的信息.所以,用C#程序实现xml文件的增.删.改 ...
- selector是在文件夹drawable中进行定义的xml文件。
获取Drawable对象: Resources res = mContext.getResources(); Drawable myImage = res.getDrawable(R.drawable ...
- selector是在文件夹drawable中进行定义的xml文件转载 https://www.cnblogs.com/fx2008/p/3157040.html
获取Drawable对象: Resources res = mContext.getResources(); Drawable myImage = res.getDrawable(R.drawable ...
随机推荐
- Popup 解决位置不随窗口/元素FrameworkElement 移动更新的问题
原文:Popup 解决位置不随窗口/元素FrameworkElement 移动更新的问题 Popup弹出后,因业务需求设置了StaysOpen=true后,移动窗口位置或者改变窗口大小,Popup的位 ...
- Android studio 无法启动安卓模拟器
1.通过Android SDK Manager在extra中,找到并选中了那个Intel x86 Emulator Accelerator (HAXM) 2.手动启动HAXM 去对应的sdk\e ...
- 一款有意思的 Qt 飞行仪表控件
最近在网上偶然发现一款Qt飞行仪表板控件,真的很酷哦! 是一款开源软件, 直接编译运行: 美工还是不错的! 控件操作非常简单: void MainWindow::timerEvent( QTimer ...
- C#中的Lambda总结
Lambda的前世今生 早在C# 1.0 时,C#中就引入了委托(delegate)类型的概念.通过使用这个类型,我们可以将函数作为参数进行传递.在某种意义上,委托可理解为一种托管的强类型的函数指针. ...
- Struts2——(5)转发和重定向(跨业务模块)
一.重定向redirect(默认是转发dispatcher)和转发的区别? 1.重定向浏览器的网址发生变化(相当于请求了两次),转发浏览器的网址不发生变化(只请求了一次). 2.重定向的过程:发送请求 ...
- muduo源代码分析--Reactor在模型muduo使用(两)
一. TcpServer分类: 管理所有的TCP客户连接,TcpServer对于用户直接使用,直接控制由用户生活. 用户只需要设置相应的回调函数(消息处理messageCallback)然后TcpSe ...
- iOS开展block说明
源代码下载 浅谈block使用方法 对于block他用着确实方便,好多人都非常迷茫,这里写了一个Demo解说block的使用方法 好多人都觉得block是用于后一个界面向前一个界面传值用的,事实上更详 ...
- Android中WebView的相关使用
近期做的项目中,遇到个非常棘手的问题: 客户给我的数据是有限制的,因此,在返回某条详细页面内容的时候,他仅仅能给我一个html片段,里面包括 文字,图片以及附件的下载地址.假设网页模版规范的爱比較好说 ...
- 关于iis里面 .net framework 版本的切换
然而,即便这样还是不够的 在iis上浏览网站会报以下错误: 这是什么原因呢?这是因为应用程序池中没有使用asp.net v4.0 网站程序是用v4.0写的,所以我们要用4.0的程序池版本,当前应用程序 ...
- Unity3d基础组件 (Component) 和脚本 (Script) 关系
原版的:http://edu.china.unity3d.com/learning_document/getData?file=/Manual/TheComponent-ScriptRelations ...