XML文件读写
这里是利用COM组建对xml文件进行操作,所以程序进入时要进行COM组件的初始化和卸载
::CoInitialize(NULL); 和?::CoUninitialize();要对应
为了不影响其他地方的操作,最好把这个放在项目的开始和结束
你也可以使用AfxOleInit();他对CoInitialize进行了封装,具体的区别可以到网上查一下
另外确保安装了MS XML Parser 运行库
?
?
使用时需要加上
#import <msxml3.dll>?
下面的两个函数就是对xml文件的操作,大部分操作都已涉及
?
///////////////////////////////////////////////////////////////////////////////#import <msxml3.dll>typedef MSXML2::IXMLDOMDocumentPtr DOMDocumentPtr;typedef MSXML2::IXMLDOMElementPtr DOMElementPtr;typedef MSXML2::IXMLDOMProcessingInstructionPtrDOMProInstructionPtr;typedef MSXML2::IXMLDOMNamedNodeMapPtr DOMNamedNodeMapPtr;typedef MSXML2::IXMLDOMNodeListPtr DOMNodeListPtr;typedef MSXML2::IXMLDOMNodePtr DOMNodePtr;typedef MSXML2::IXMLDOMTextPtr DOMTextPtr;///////////////////////////////////////////////////////////////////////////////int ReadXML(CString szXMLFile){if (szXMLFile.IsEmpty())return -1;DOMDocumentPtr pXMLDoc;CString szText;// 初始化COM组件,必须与::CoUninitialize();相对应// 这里可以这么使用,但以后尽量在程序开始调用,程序结束卸载,否则可能会影响到其他地方使用// 用AfxOleInit();也可以,但也必须确保只调用了一次,最好放在程序的开始::CoInitialize(NULL);// 创建DOMDocument对象,并判断是否创建成功HRESULThr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));if(!SUCCEEDED(hr)){MessageBox(NULL, "无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!", "Error", MB_ICONERROR|MB_OK);return -1;}if(pXMLDoc->load(_variant_t(szXMLFile)) == FALSE){MessageBox(NULL, "无法打开存档!", "Error", MB_ICONERROR|MB_OK);return -2;}// 是否有根节点,取得根节点DOMElementPtr pRootElem = pXMLDoc->GetdocumentElement();if (pRootElem == NULL)return -3;// 取得根节点的名字szText = (char*)(pRootElem->GetnodeName());// 在根节点下查找名叫Globals的节点并取得DOMNodePtr pGlobalNode = pRootElem->selectSingleNode("Globals");if (pGlobalNode == NULL)return -3;// 取得属性列表DOMNamedNodeMapPtr pNodeMap = pGlobalNode->Getattributes();// 根据名字直接取得属性节点并获取值DOMNodePtr pAttribNode = pNodeMap->getNamedItem("Attrib");szText = (char *)(pAttribNode->Gettext());pAttribNode = pNodeMap->getNamedItem("作用");szText = (char *)(pAttribNode->Gettext());// 另外在有些情况下Node可以转换成Element使用DOMElementPtr pGlobalElem = pGlobalNode;szText = (char*)(_bstr_t)(pGlobalElem->getAttribute("Attrib"));szText = (char*)(_bstr_t)(pGlobalElem->getAttribute("作用"));// 如果不知道名字可以取得属性的个数,逐个查找属性long len = pNodeMap->Getlength();for (int i=0; i<len; ++i){pAttribNode = pNodeMap->Getitem(i);szText = (char *)(pAttribNode->GetnodeName());// 取得属性名字szText = (char *)(pAttribNode->Gettext());// 取得属性值}DOMNodePtr pTempNode;// 取得Globals下的子节点if((pTempNode = pGlobalNode->GetfirstChild())){szText = (char*)pTempNode->GetnodeName();szText = (char*)pTempNode->Gettext();// 循环取得相邻的节点while((pTempNode = pTempNode->GetnextSibling())){szText = (char*)pTempNode->GetnodeName();szText = (char*)pTempNode->Gettext();}}// 从根节点中查找Data的子节点DOMNodePtr pDataNode = pRootElem->selectSingleNode("Data");if (pDataNode == NULL)return -1;// 从Data节点下列取出所有叫Data的节点DOMNodeListPtr pDataList = pDataNode->selectNodes("Data");len = pDataList->Getlength();for(i=0; i<len; ++i){pTempNode = pDataList->Getitem(i);szText = (char*)pTempNode->GetnodeName();szText = (char*)pTempNode->Gettext();}// 确保卸载掉所有的对象才能调用CoUninitializeif(pNodeMap)pNodeMap.Detach();if(pAttribNode)pAttribNode.Detach();if(pTempNode)pTempNode.Detach();if(pGlobalNode)pGlobalNode.Detach();if(pGlobalElem)pGlobalElem.Detach();if(pDataNode)pDataNode.Detach();if(pDataList)pDataList.Detach();if(pRootElem)pRootElem.Detach();if(pXMLDoc)pXMLDoc.Detach();// 卸掉COM,必须与CoInitialize对应::CoUninitialize();return 0;}int SaveXML(CString szXMLFile){DOMDocumentPtr pXMLDoc;CString szText;// 初始化COM组件,必须与::CoUninitialize();相对应// 这里可以这么使用,但以后尽量在程序开始调用,程序结束卸载,否则可能会影响到其他地方使用// 用AfxOleInit();也可以,但也必须确保只调用了一次,最好放在程序的开始::CoInitialize(NULL);// 创建DOMDocument对象,并判断是否创建成功HRESULThr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));if(!SUCCEEDED(hr)){MessageBox(NULL, "无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!", "Error", MB_ICONERROR|MB_OK);return -1;}// 创建头节点DOMProInstructionPtr pXmlProNode = pXMLDoc->createProcessingInstruction(_bstr_t("xml"),_bstr_t("version="1.0" encoding = "GB2312""));pXMLDoc->appendChild((MSXML2::IXMLDOMNodePtr)pXmlProNode);pXmlProNode.Detach();//以后不再用的,卸掉// 创建并添加根节点// 创建一个节点DOMElementPtr pXmlRoot = pXMLDoc->createElement("root");// 添加到文档中pXMLDoc->appendChild(pXmlRoot);// 创建一个节点DOMElementPtr pGlobalNode = pXMLDoc->createElement("Globals");// 添加到根节点中pXmlRoot->appendChild(pGlobalNode);// 添加两个属性pGlobalNode->setAttribute("Attrib", "Value");pGlobalNode->setAttribute("作用", "记录全局数据");DOMElementPtr pTempNode = pXMLDoc->createElement("Author");pTempNode->Puttext("Ren.Xia");// 添加内容pGlobalNode->appendChild(pTempNode);pTempNode.Detach();pTempNode = pXMLDoc->createElement("Date");pTempNode->Puttext("2011-02-12");// 添加内容pGlobalNode->appendChild(pTempNode);pTempNode.Detach();pGlobalNode.Detach();// 在Root下创建Data子节点DOMElementPtr pDataNode = pXMLDoc->createElement("Data");pDataNode->setAttribute("Attrib", "Value");pDataNode->setAttribute("作用", "记录数据");pXmlRoot->appendChild(pDataNode);for (int i=0; i<100; ++i){pTempNode = pXMLDoc->createElement("Data");szText.Format("%d", i);pTempNode->Puttext((_bstr_t)szText);pDataNode->appendChild(pTempNode);pTempNode.Detach();}pDataNode.Detach();// 判断名字是否为空if (szXMLFile.IsEmpty()){pXmlRoot.Detach();pXMLDoc.Detach();return -2;}// 存储并判断是否成功hr = pXMLDoc->save((LPCTSTR)szXMLFile);pXmlRoot.Detach();pXMLDoc.Detach();if(!SUCCEEDED(hr)){MessageBox(NULL, "无法保存!", "Error", MB_ICONERROR|MB_OK);return -3;}MessageBox(NULL, "保存完毕!", "Error", MB_ICONASTERISK|MB_OK);// 卸掉COM,必须与CoInitialize对应::CoUninitialize();return 0;}
?
另外如果知道一个节点的名字"Data",但是不知道在哪一层,那个树下
可以在查找时名字前加个"//"这样就表示在任意一层查找 ?
?
pRootElem->selectSingleNode(" //Data");?
?