VC 使用msxml6.dll动态链接库中的函数读写XML文件
来源:互联网 发布:增广贤文 知乎 编辑:程序博客网 时间:2024/04/29 16:22
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之间的TextCString 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"//查询到一个或多个节点,返回第一个节点;如果没有查询的任何节点返回 NothingpElemNode = (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); //获取子结点个数 1for(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); //初始化COMMSXML2::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); //初始化COMm_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 == FALSEMessageBox("加载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")个数 2for(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); //初始化COMm_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 == FALSEMessageBox("加载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;}此更新工程下载连接。2014年3月11日
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
- 编译VC++类的动态链接库DLL 导出类及其中的函数
- VC动态链接库DLL
- VC动态链接库DLL
- 动态链接库dll文件的使用
- VC中动态链接库dll文件的调用
- VC++中DLL(动态链接库)使用的若干问题
- 【动态链接库】VC++2010中创建和使用动态链接库dll
- 【VC DLL】VC++动态链接库(DLL)编程深入浅出
- 载入资源中的动态链接库(dll)文件
- VC中制作DLL 动态链接库 函数回调MFC dll
- VC++动态链接库(DLL)编程深入浅出
- VC++动态链接库(DLL)编程深入浅出
- VC++动态链接库(DLL)编程深入浅出
- VC++动态链接库(DLL)编程深入浅出
- VC++动态链接库(DLL)编程深入浅出
- VC动态链接库DLL 开发技巧
- matlab编程入门学习(1)
- .NET动态设置和显示Titel、KeyWords、Description
- Android 内存泄露问题
- 屏蔽CTRL+ALT+DEL热键
- ArcGIS栅格重采样方法
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
- SHELLEXECUTEINFO 和 ShellExecuteEx的使用
- mysql中时间日期的处理
- NDK不用cygwin,只用eclipse开发,照样能编译成 .so文件
- 文本框只能输入数字
- 清空vector容器的方法
- 第一招:Powerdesigner15-物理模型-导出建表sql语句
- Android action bar 为什么有时有,有时没有
- Android WiFi自动连接的优先级的实现情况 M