zoukankan      html  css  js  c++  java
  • VC 使用msxml6.dll动态链接库中的函数读写XML文件

    VC 使用msxml6.dll动态链接库中的函数读写XML文件

    目录

    1 引言

    2 .dll使用方法

    3 常用函数总结

    4 实例应用

    5 运行效果预览

    6 补充说明

    7 不足之处

    8 更新

     

    引言:

           在C:WINDOWSsystem32下有msxml3.dll 和 msxml6.dll两个动态链接库可以提供操作XML文件的函数。这两个只是版本不同,使用其一即可。

     

    .dll使用方法:

            #import "C:\WINDOWS\system32\msxml6.dll"
            using namespace MSXML2;

     

    常用函数总结:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. a.创建xml文档对象  
    2.     MSXML2::IXMLDOMDocumentPtr pDoc; //声明xml文档指针  
    3.     HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));  //实例化xml文档对象  
    4.     delete pDoc;    
    5. b.创建"Element"、添加"Element"到xml文档对象中  
    6.     MSXML2::IXMLDOMElementPtr xmlRoot;  //声明"Element"指针  
    7.     pDoc->raw_createElement( (_bstr_t)(char*)"China", &xmlRoot);  //创建"Element"  
    8.     pDoc->raw_appendChild(xmlRoot, NULL);  //添加"Element"到xml文档对象中  
    9.   
    10. c.为"Element"添加属性及其属性值  
    11.     MSXML2::IXMLDOMElementPtr pElemNode;  
    12.     pDoc->raw_createElement( (_bstr_t)(char*)"City", &childNode);  
    13.     pElemNode->setAttribute("population","7000");  //1:属性名  2:属性值  
    14.   
    15. d.元素之间的Text操作  
    16.     MSXML2::IXMLDOMElementPtr pElemNode;  //声明一个元素(Element)指针  
    17.     pElemNode->Puttext("shanghai");  //设置Element之间的Text  
    18.     CString strElemText = (char*)(_bstr_t)pElemNode->Gettext();  //获取Element之间的Text  
    19.           
    20.  e.创建、保存XML文档  
    21.     pDoc->save(".\test.xml");  //创建、保存并关闭xml文档  
    22.   
    23. f.加载xml文档  
    24.     MSXML2::IXMLDOMDocumentPtr pDoc;  
    25.     HRESULT loadrs = pDoc->load(".\test.xml");  //加载xml文档  
    26.   
    27. g.查询"Element"  
    28.     //查询到一个或多个节点,返回第一个节点;如果没有查询的任何节点返回 Nothing  
    29.     pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//City"));  //获取元素的信息  
    30.   
    31. h.与xml一起常用的容器  
    32.     //IXMLDOMNamedNodeMap 是一个结点容器,允许通过name或index访问     
    33.     //这个容器是通常用于容纳属性      
    34.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;  
    35.   
    36.     //IXMLDOMNodeList 是一个动态容器,也就是说:添加、删除结点    
    37.     //以及改变结点,都会立即更新容器       
    38.     MSXML2::IXMLDOMNodeListPtr nodeList = NULL;  
    39.   
    40.     //结点指针  
    41.     MSXML2::IXMLDOMNodePtr pAttrItem = NULL;  
    42.   
    43. j.容器的使用  
    44.     pElemNode->get_attributes(&pAttrs); //获取pElemNode指向的元素的属性集  
    45.     pElemNode->get_childNodes(&nodeList);  //获取子节点  
    46.   
    47.     long nCount, iCount;  
    48.     //IXMLDOMNamedNodeMapPtr->get_length(long* )  返回容器中保存属性的个数  
    49.     pAttrs->get_length(&nCount);     //获取结点属性个数 2  
    50.       
    51.     //IXMLDOMNodeListPtr->get_length(long* ) 返回容器中保存结点的个数  
    52.     nodeList->get_length(&iCount);   //获取子结点个数  1  
    53.     for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中  
    54.     {  
    55.         CString strElemText = (char*)(_bstr_t)pElemNode->Gettext();  //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本  
    56.         m_list.InsertItem(i,strElemText);  //1:行索引  2:待添加的字串  
    57.         for(int j = 0; j < nCount; j++ )  
    58.         {  
    59.             pAttrs->get_item(j,&pAttrItem);  //获取结点信息-结点  
    60.             //CString strAttrName = (char*)(_bstr_t)pAttrItem->nodeName;  //当前元素(Element)指定属性的名称  
    61.             CString strAttrVale = (char*)(_bstr_t)pAttrItem->nodeTypedValue;  //当前元素指定属性的值  
    62.               
    63.             m_list.SetItemText(i,j+1,strAttrVale);  //1:行索引  2:列索引  3:待添加的字串  
    64.             //m_list.SetItemText(i,2,strAttrName);   
    65.         }  
    66.     }  
    67.   
    68. k.重要的函数  
    69.   <1>获取子元素  
    70.      IXMLDOMNodeListPtr nodelist=NULL;  
    71.      pElemNode->get_childNodes(&nodeList);   //两个函数是等效的  
    72.      nodelist = pElemNode->GetchildNodes();  
    73.      保存pElementNode元素下的所有指向子元素的指针。  
    74.         <book category="children">  
    75.             <title lang="en">Harry Potter</title>  
    76.             <author>J K. Rowling</author>  
    77.             <year>2005</year>  
    78.             <price>29.99</price>  
    79.         </book>  
    80.      如pElement指向 <book> </book>,则<title>、<author>、<year>、<price>都是pElement的子结点(或称为子元素)  
    81.     
    82.   <2>返回nodeList容器中当前结点(应该是一个游标指针来实现的)的下一个结点。  
    83.      nodeList->nextNode()  
    84.      例子:  
    85.      pElemNode = pDoc->selectSingleNode("//China");  //获取元素的信息  
    86.      MSXML2::IXMLDOMNodeListPtr nodeList = NULL;  //list容器  
    87.      pElemNode->get_childNodes(&nodeList);   //获取子节点  
    88.      pCurNode = nodeList->nextNode();  
    89.   
    90.   <3>pCurNode->GetnextSibling()  
    91.      Retrieves the next sibling(元素处于同一树层级中) of this node in the parent's child list.如果无此节点,则返回 null。  
    92.      备注:目前用法没有验证。  
    93.      可配合下面两个函数使用:  
    94.      get_firstChild  Retrieves the first child of this node.  
    95.      get_lastChild   Retrieves the last child of this node.  
    96.      
    97.   <4>获取元素的属性值  
    98.      <City population="12000" name="Wuhan"> </City>  
    99.      m_pCurNode指向<City> </City>这个元素  
    100.      CString varVal = m_pCurNode->getAttribute("population");  //varVal = "12000"  
    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1.  ------特别注意--------  
    2.            <China>  
    3.                <City population="7000" area="2000">  
    4.                   <Area> QingShan </Area>  
    5.                </City>    
    6.            </China>   
    7.         如果pElemNode当前指向<City> </City>这个节点,  
    8.         那么               
    9.         CString strElemText = (char*)(_bstr_t)pElemNode->Gettext();   
    10.         strElemText的值就是“QingShan”  

    实例应用

    应用1:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. 测试用的xml文件-- test.xml  
    2. <China>  
    3.     <City population="7000" area="2000">shanghai</City>  
    4.     <City population="39999" area="3322">beijing</City>  
    5.     <City population="5000" area="40000">Wuhan</City>  
    6. </China>  



    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #import "C:\WINDOWS\system32\msxml6.dll"   
    2. using namespace MSXML2;  
    3.   
    4. //创建xml文件  
    5.  void COperateXMLDlg::OnBtnCreate()   
    6. {  
    7.     // TODO: Add your control notification handler code here  
    8.     ::CoInitialize(NULL);  //初始化COM  
    9.     MSXML2::IXMLDOMDocumentPtr pDoc;  
    10.     MSXML2::IXMLDOMElementPtr xmlRoot;  
    11.     HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));  
    12.     if(!SUCCEEDED(hr))  
    13.     {  
    14.         MessageBox("XML文件创建失败");  
    15.         return ;  
    16.     }  
    17.   
    18.     pDoc->raw_createElement( (_bstr_t)(char*)"China", &xmlRoot);  
    19.     pDoc->raw_appendChild(xmlRoot, NULL);  
    20.   
    21.     MSXML2::IXMLDOMElementPtr pElemNode;  
    22.     pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);  
    23.     pElemNode->Puttext("shanghai");  
    24.     pElemNode->setAttribute("population","7000");  
    25.     pElemNode->setAttribute("area","2000");  
    26.     xmlRoot->appendChild(pElemNode);  
    27.   
    28.     pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);  
    29.     pElemNode->Puttext("beijing");  
    30.     pElemNode->setAttribute("population","39999");  
    31.     pElemNode->setAttribute("area","3322");  
    32.     xmlRoot->appendChild(pElemNode);  
    33.   
    34.     pDoc->raw_createElement( (_bstr_t)(char*)"City", &pElemNode);  
    35.     pElemNode->Puttext("Wuhan");  
    36.     pElemNode->setAttribute("population","5000");  
    37.     pElemNode->setAttribute("area","40000");  
    38.     xmlRoot->appendChild(pElemNode);  
    39.   
    40.     pDoc->save(".\test.xml");  
    41.     //如何释放pDoc占有的内存  
    42.     ::CoUninitialize();  //卸载COM  
    43. }  
    44.   
    45. //读取xml文件  
    46. void COperateXMLDlg::OnBtnGetXML()   
    47. {  
    48.     // TODO: Add your control notification handler code here  
    49.     ::CoInitialize(NULL);  //初始化COM  
    50.     m_list.DeleteAllItems();  //m_list是ListControl控件绑定的一个Value类型的变量  
    51.     MSXML2::IXMLDOMDocumentPtr pDoc;  //创建一个xml文档指针  
    52.     HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));  //实例化文档指针  
    53.     if(!SUCCEEDED(hr))  
    54.     {  
    55.         MessageBox("加载XML错误");  
    56.             return ;  
    57.     }  
    58.     VARIANT_BOOL loadrs = pDoc->load(".\test.xml");  //加载xml文档  
    59.     if( -1 != loadrs )  //查看load函数的定义(msxml3.tli)发现返回类型是VARIANT_BOOL,-1 == TRUE、0 == FALSE  
    60.         MessageBox("加载XML错误");  
    61.     MSXML2::IXMLDOMElementPtr pElemNode;  //声明一个元素(Element)指针  
    62.   
    63.     // 在树中查找名为City的节点," // "表示在任意一层查找  
    64.     //selectSingleNode方法如果查询到一个或多个节点,返回第一个节点;如果没有查询的任何节点返回 Nothing  
    65.     //SelectNodes("//City")返回一个NodeList对象,可能包含多个节点  
    66.     pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//China"));  //获取元素的信息  
    67.   
    68.     //MSXML2::DOMNodeType nodeType;  //结点类型  
    69.     //childNode->get_nodeType(&nodeType);  
    70.   
    71.     //IXMLDOMNamedNodeMap 是一个结点容器,允许通过name或index访问     
    72.     //这个容器是通常用于容纳属性      
    73.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;  
    74.   
    75.     //IXMLDOMNodeList 是一个动态容器,也就是说:添加、删除结点    
    76.     //以及改变结点,都会立即更新容器       
    77.     MSXML2::IXMLDOMNodeListPtr nodeList = NULL;  
    78.   
    79.     //结点指针  
    80.     MSXML2::IXMLDOMNodePtr pAttrItem = NULL;  
    81.     //pElemNode->get_attributes(&pAttrs); //获取pElemNode指向的元素的属性集  
    82.     pElemNode->get_childNodes(&nodeList);  //获取子节点  
    83.   
    84.     long nCount, iCount;  
    85.     MSXML2::IXMLDOMElementPtr pCurNode;  
    86.     //IXMLDOMNamedNodeMapPtr->get_length(long* )  返回容器中保存属性的个数  
    87.     //pAttrs->get_length(&nCount);     //获取结点属性个数 2  
    88.     //IXMLDOMNodeListPtr->get_length(long* ) 返回容器中保存结点的个数  
    89.   
    90.     nodeList->get_length(&iCount);   //获取子结点(此处指"China"元素下的子元素"City")个数  2  
    91.     for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中  
    92.     {  
    93.         pCurNode = nodeList->nextNode();  
    94.         CString strPoupula = pCurNode->getAttribute("population");  
    95.         CString strArea= pCurNode->getAttribute("area");  
    96.         CString strElemText = (char*)(_bstr_t)pCurNode->Gettext();  //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本  
    97.           
    98.         m_list.InsertItem(i,strElemText);  //1:行索引  2:待添加的字串  
    99.         m_list.SetItemText(i,1,strPoupula); //1:行索引  2:列索引  3:待添加的字串  
    100.         m_list.SetItemText(i,2,strArea);  
    101.     }  
    102.     ::CoUninitialize();  //卸载COM  
    103. }  

    运行效果预览:

                   实例下载链接,上传到CSDN的资源库中,0分资源,支持VC6和VS2010IDE。下载此工程实例--VC6/VS2010

    应用2:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <China>  
    2.     <Provious name="Hubei">  
    3.         <City population="1" area="100">YiChang</City>  
    4.         <City population="2" area="40000">Wuhan</City>  
    5.     </Provious>  
    6.     <Provious name="HeBei">  
    7.         <City population="39999" area="3322">beijing</City>  
    8.         <City population="39999" area="3322">QingDao</City>  
    9.     </Provious>  
    10.     <Provious name="JiangSu">  
    11.         <City population="7000" area="2000">shanghai</City>  
    12.     </Provious>  
    13. </China>  
    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void COperateXMLDlg::OnBtnGetXML()   
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     ::CoInitialize(NULL);  //初始化COM  
    5.     m_list.DeleteAllItems();  
    6.     MSXML2::IXMLDOMDocumentPtr pDoc;  //创建一个xml文档指针  
    7.     HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));  //实例化文档指针  
    8.     if(!SUCCEEDED(hr))  
    9.     {  
    10.         MessageBox("加载XML错误");  
    11.             return ;  
    12.     }  
    13.     VARIANT_BOOL loadrs = pDoc->load(".\test.xml");  //加载xml文档  
    14.     if( -1 != loadrs )  //查看load函数的定义(msxml3.tli)发现返回类型是VARIANT_BOOL,-1 == TRUE、0 == FALSE  
    15.         MessageBox("加载XML错误");  
    16.     MSXML2::IXMLDOMElementPtr pElemNode;  //声明一个元素(Element)指针  
    17.   
    18.     // 在树中查找名为City的节点," // "表示在任意一层查找  
    19.     pElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode("//China"));  //获取元素的信息  
    20.          
    21.         MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;   
    22.     MSXML2::IXMLDOMNodeListPtr nodeList = NULL;  
    23.     MSXML2::IXMLDOMNodePtr pAttrItem = NULL;  
    24.   
    25.     pElemNode->get_childNodes(&nodeList);  //获取子节点  
    26.   
    27.     long nCount, iCount,index=0;  
    28.     MSXML2::IXMLDOMElementPtr pCurNode,pChildCurNode;  
    29.   
    30.     nodeList->get_length(&iCount);     
    31.     for(int i = 0; i < iCount; i++ ) //根据需要可以添加数据到ListControl中  
    32.     {  
    33.         pCurNode = nodeList->nextNode();  
    34.         MSXML2::IXMLDOMNodeListPtr ChildnodeList = NULL;  
    35.         pCurNode->get_childNodes(&ChildnodeList);  
    36.         ChildnodeList->get_length(&nCount);  
    37.         for(int j=0; j < nCount; j++ )  
    38.         {  
    39.             pChildCurNode = ChildnodeList->nextNode();  
    40.             CString strPoupula = pChildCurNode->getAttribute("population");  
    41.             CString strArea= pChildCurNode->getAttribute("area");  
    42.             CString strElemText = (char*)(_bstr_t)pChildCurNode->Gettext();  //获取Element标签之间的Text文本,Puttext(LPCSTR)为设置Text文本  
    43.           
    44.             m_list.InsertItem(index,strElemText);  //1:行索引  2:待添加的字串  
    45.             m_list.SetItemText(index,1,strPoupula);   
    46.             m_list.SetItemText(index,2,strArea);  
    47.             index++;  
    48.         }  
    49.     }  
    50.     ::CoUninitialize();  //卸载COM  
    51. }  



    补充说明:

            项目中导入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文件中。代码如下

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. BOOL AddXMLHeadString()  
    2. {  
    3.     //由于必须从文件最开头添加字符会覆盖掉原来的字符,所以采用下面的方法解决这个问题  
    4.     //先把原始文件读取出来,然后加上xml的文件头字符串,再写回去。  
    5.     //char readBuf[]  
    6.     CString fileName(_T(".\test.xml") );  
    7.     CStdioFile myfile;  
    8.     CFileException fileExcp;  
    9.     BOOL bRet = myfile.Open(fileName,CFile::typeText|CFile::modeReadWrite,&fileExcp);  
    10.     if( bRet )  
    11.     {     
    12.         /*一个稀奇事:如果1 、2 部分调换顺序就会使myfile.Read读取文件内容异常,但是两者的顺序是无关紧要的*/  
    13.         //1.读取原有文件的内容  
    14.         UINT fileLen = myfile.GetLength();  
    15.         char * readBuf = new char[fileLen];  
    16.         myfile.Read(readBuf,fileLen);  
    17.           
    18.         //2.如果已经有了XML文件头就不添加  
    19.         CString strXMLHeader;  
    20.         myfile.ReadString(strXMLHeader);  
    21.         CString xmlHeader = _T("<?xml version="1.0" encoding="gb2312"?>");  
    22.         if(  xmlHeader== strXMLHeader )   
    23.             return TRUE;  
    24.   
    25.         myfile.Close();  
    26.   
    27.         //3.合成完整的xml文件  
    28.         CStdioFile newFile;  
    29.         BOOL bRetNewFile = newFile.Open(fileName,CFile::typeText|CFile::modeCreate|CFile::modeReadWrite,&fileExcp);  
    30.         if( bRetNewFile )  
    31.         {  
    32.             newFile.Seek(0,CFile::end);  
    33.             newFile.WriteString(_T("<?xml version="1.0" encoding="gb2312"?> "));  
    34.             newFile.Seek(0,CFile::end);  
    35.             newFile.Write(readBuf,fileLen);  
    36.             newFile.Seek(-1,CFile::end); //在文件末尾莫名其妙的多了一个‘?’,所以用了‘ ’将这个问号覆盖了,不然读取XML时会出错  
    37.             newFile.WriteString(_T(" "));  
    38.         }  
    39.     }  
    40.     char *errinfo = new char [255];  
    41.     fileExcp.GetErrorMessage(errinfo,255);  
    42.     delete[] errinfo;  
    43.   
    44.     return bRet;  
    45. }  

                      此更新工程下载连接。2014年3月11日

    http://blog.csdn.net/qq2399431200/article/details/17583171

    http://z.download.csdn.net/detail/qq2399431200/7022299

  • 相关阅读:
    新版淘淘商城_01_简介
    JavaMail之-通过邮件激活账号
    javaMail发送邮件
    JavaMail学习之一-邮件传输协议
    解决ios的safari不能自动播放audio问题(以及部分微信也不能自动播放)
    css3背景渐变色
    jq杂记
    各种“分享按钮“方法总结
    底部导航统一高度
    js 与或运算符 || && 妙用
  • 原文地址:https://www.cnblogs.com/findumars/p/6568652.html
Copyright © 2011-2022 走看看