這里是利用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::IXMLDOMProcessingInstructionPtr DOMProInstructionPtr; 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對象,并判斷是否創建成功 HRESULT hr = 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(); } // 確保卸載掉所有的對象才能調用CoUninitialize if(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對象,并判斷是否創建成功 HRESULT hr = 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",但是不知道在哪一層,那個樹下
可以在查找時名字前加個"http://"這樣就表示在任意一層查找
pRootElem->selectSingleNode(" //Data");
-
本文附件下載:
- XML.rar (484.4 KB)