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 ...
随机推荐
- javaScript显示实时时间输出
实时时间输出 <script> function getDateTime(){ var a = new Date(); var year = a.getFullYear(); var mo ...
- UUID不失精度,长度改进
在使用到uuid的时候,往往头疼于它的长度(如1bfe50d8-544e-4e8a-95b8-199ceff15268),于是乎就有了改写uuid的各种方法 1.去除"-"的uui ...
- gridview分页
protected void lnkbtnFrist_Click(object sender, EventArgs e) { //首页 ; this.ReadData(); } protected v ...
- 如何提高自己的java开发功底
1.拥有扎实的基础和深刻理解OO原则 对于Java程序员,深刻理解Object Oriented Programming(面向对象编程)这一概念是必须的.没有OOPS的坚实基础,就领会不了像Java这 ...
- Smali相关的基础知识点
通过本篇博客的学习,相信你可以无压力的读懂Smali语言文件,并可以将Smali还原成java!!! 其实Smali语言并不是很难,如果你有一些汇编指令的基础,学习Smali就更加简单了,有兴趣的可以 ...
- SQLite从Excel文件中导入数据
元数据 另存为.csv格式 用记事本打开 打开后的数据 Android客户端开发的时候使用了SQLite数据库,为了测试,需要将一些excel文件中的数据导入到数据库的表中,下面是几个步骤: 数据库表 ...
- Linux性能测试 ss命令
ss即socket state,也就是说,是可以查看系统中socket的状态的.我们可以用netstat,但为什么还要用ss这个工具呢,当然ss也是有好处的.当我们打开的socket数量很多时,net ...
- 一些自成系统、完备的教程(链接、博客、github等)
0. Linus shell Advanced Bash-Scripting Guide 1. latex Some applicable LATEX's info 14 课的个人 CV 制作: 15 ...
- windows安装Oracle10G
1.解压文件10201_database_win32.zip.并双击解压文件夹下的setup.exe,出现安装界面,例如以下: 输入口令和确认口令.如:password,点击下一步,出现例如以下 ...
- 经典c开源项目
1. Webbench Webbench是一个在Linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连 ...