1. 程式人生 > >MFC操作XML配置檔案的兩種方式:DOM 和 MSXML

MFC操作XML配置檔案的兩種方式:DOM 和 MSXML

這幾天做VC專案涉及到了建立xml配置檔案這方面的問題,糾結了好多天,嘗試了N種方法,終於完成了工作任務,現在和大家分享下:

 我參考瞭如下的資料:

XML DOM 例項:http://www.w3school.com.cn/example/xdom_examples.asp

VC++中操作XML(MFC、SDK):http://www.cnblogs.com/lingyun1120/archive/2011/11/02/2232709.html

MFC 使用MsXML讀寫XML檔案:http://www.douban.com/note/150604463/

通過看這些資料發現使用DOM比使用MSXML程式碼要簡潔!但DOM網上的資料都不是很全!還是有許多小問題解決不了,所以綜合之下還是選用MSXML 做:

現在貼程式碼:

	DataBind();//載入資料

	MSXML2::IXMLDOMDocumentPtr pDoc;//生成xml檔案型別,定義名為pDoc 
	MSXML2::IXMLDOMElementPtr xmlRoot;//生成第一個節點,定義名為xmlRoot 
	//以下幾行用於檢驗xml檔案是否生成,照此格式寫就行了
	HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30)); 
	if(!SUCCEEDED(hr)) 
	{ 
		MessageBox(_T("無法建立DOMDocument	物件,請檢查是否安裝了MSXMLParser 執行庫!"));
	}
	//建立並新增Xml	文件宣告
	MSXML2::IXMLDOMProcessingInstructionPtr pXMLProc = NULL;
	pXMLProc = pDoc->createProcessingInstruction(_T("xml"),_T("version='1.0' encoding='UTF-8'"));
	_variant_t vNullVal;
	vNullVal.vt = VT_NULL;
	pDoc->insertBefore(pXMLProc, vNullVal);

	// 建立根結點
	_variant_t varNodeType((short)MSXML2::NODE_ELEMENT);
	MSXML2::IXMLDOMNodePtr pXMLNodeRoot= NULL; 
	pXMLNodeRoot = pDoc->createNode(varNodeType, _T("Root"), _T(""));
	// 新增根結點
	pDoc->appendChild(pXMLNodeRoot);
	// 建立並新增下級結點
	MSXML2::IXMLDOMNodePtr pXMLNodePatients= NULL; 
	pXMLNodePatients = pXMLNodeRoot->appendChild(pDoc->createElement(_T("Patients")));

        // 建立下級元素結點(PatientID)
        MSXML2::IXMLDOMElementPtr pXMLElePatientID = NULL;
        pXMLElePatientID = pDoc->createElement(_T("PatientID"));
        pXMLElePatientID ->appendChild(pDoc->createTextNode((_bstr_t)strPatientID));
        // 建立並設定下級結點屬性
        MSXML2::IXMLDOMAttributePtr pXMLAttr = NULL;
        pXMLAttr = pDoc->createAttribute(_T("ID"));
        pXMLAttr->nodeTypedValue = "PatientID";
        pXMLElePatientID->attributes->setNamedItem(pXMLAttr);
        pXMLNodePatients->appendChild(pXMLElePatientID);

        // 建立下級元素結點(Patient)
        MSXML2::IXMLDOMElementPtr pXMLElePatient = NULL;
        pXMLElePatient = pDoc->createElement(_T("Patient"));
        pXMLElePatient->appendChild(pDoc->createTextNode((_bstr_t)strPatient));
        pXMLAttr = pDoc->createAttribute(_T("ID"));
        pXMLAttr->nodeTypedValue = "Patient";
        pXMLElePatient->attributes->setNamedItem(pXMLAttr);
        pXMLNodePatients->appendChild( pXMLElePatient);

        //輸出XML資料檔案

        CFileDialog hFileDlg(FALSE,NULL,NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_READONLY,
        TEXT("支援的XML檔案 (XML(*.xml)|*.XML||)"),NULL);
        hFileDlg.m_ofn.nFilterIndex=1;
        hFileDlg.m_ofn.hwndOwner=m_hWnd;
        hFileDlg.m_ofn.lStructSize=sizeof(OPENFILENAME);
        hFileDlg.m_ofn.lpstrTitle=TEXT("儲存XML資料檔案...\0");
        hFileDlg.m_ofn.nMaxFile=MAX_PATH;

       if(hFileDlg.DoModal() == IDOK)
       {
          strPath = hFileDlg.GetPathName();
          pDoc->save((_bstr_t)strPath);//儲存檔案
          isOpen=TRUE;
       }

      if (isOpen)
          MessageBox(_T("資料檔案生成成功!位置:")+strPath);
      else
         MessageBox(_T("資料生成失敗!"));

      pXMLNodeRoot.Release();
      pDoc.Release();

使用DOM檢視節點
void CMenuSimulateOutPut::ProcessNode(CComPtr<IXMLDOMNode>& spNode)
{ 
 DOMNodeType eNodeType; 
 spNode->get_nodeType(&eNodeType); 
 if (eNodeType == NODE_ELEMENT) //只有NODE_ELEMENT型別才能包含有屬性和子節點 
 { 
  BSTR  bstrName,bstrText;
  //遞迴遍歷節點屬性 
  //向介面顯示相應欄位的內容
  spNode->get_nodeName(&bstrName);
  spNode->get_text(&bstrText);
  ShowText(bstrName,bstrText);
  
  CComPtr<IXMLDOMNamedNodeMap> spNameNodeMap; 
  spNode->get_attributes(&spNameNodeMap); 
  long nLength; 
  spNameNodeMap->get_length(&nLength); 
  for (long i = 0; i != nLength; ++i) 
  { 
   CComPtr<IXMLDOMNode> spNodeAttrib; //注意屬性也是一個IXMLDOMNo
   spNameNodeMap->get_item(i, &spNodeAttrib); 
   ProcessNode(spNodeAttrib);
  }
  //遞迴遍歷子節點
  CComPtr<IXMLDOMNodeList> spNodeList;
  spNode->get_childNodes(&spNodeList);
  spNodeList->get_length(&nLength);
  for (long i=0;i!=nLength;i++)
  {
   CComPtr<IXMLDOMNode> spChildNode;
   spNodeList->get_item(i,&spChildNode);
   ProcessNode(spChildNode);
  }
 }
}
void CMenuSimulateOutPut::ShowNodes()
{
 long      i,nLen;
 CComPtr<IXMLDOMElement>spRootEle;
 spDoc->get_documentElement(&spRootEle);//根節點
 CComPtr<IXMLDOMNodeList>spNodeList;
 spRootEle->get_childNodes(&spNodeList);//子節點列表
 spNodeList->get_length(&nLen);//子節點數
 for (long i=0;i!=nLen;i++)
 {
  CComPtr<IXMLDOMNode>spNode;
  spNodeList->get_item(i,&spNode);
  ProcessNode(spNode);//節點處理函式
 }
}
void CMenuSimulateOutPut::ShowText(BSTR bstrName,BSTR bstrText)
{
 if(_bstr_t("PatientID")==_bstr_t(bstrName))
 {
  this->GetDlgItem(IDC_STATIC_PATIENTID)->SetWindowText(bstrText);
 }
 if(_bstr_t("Patient")==_bstr_t(bstrName))
 {
  this->GetDlgItem(IDC_STATIC_PATIENT)->SetWindowText(bstrText);
 }
 if(_bstr_t("Sex")==_bstr_t(bstrName))
 {
  this->GetDlgItem(IDC_STATIC_SEX)->SetWindowText(bstrText);
 }
 if(_bstr_t("Birth")==_bstr_t(bstrName))
 {
  this->GetDlgItem(IDC_STATIC_BIRTH)->SetWindowText(bstrText);
 }
 if(_bstr_t("FieldID")==_bstr_t(bstrName))
 {
  this->GetDlgItem(IDC_STATIC_FIELDID)->SetWindowText(bstrText);
 }
}
void CMenuSimulateOutPut::ShowNodes()
{
 long      i,nLen;
 CComPtr<IXMLDOMElement>spRootEle;
 spDoc->get_documentElement(&spRootEle);//根節點
 CComPtr<IXMLDOMNodeList>spNodeList;
 spRootEle->get_childNodes(&spNodeList);//子節點列表
 spNodeList->get_length(&nLen);//子節點數
 for (long i=0;i!=nLen;i++)
 {
  CComPtr<IXMLDOMNode>spNode;
  spNodeList->get_item(i,&spNode);
  ProcessNode(spNode);//節點處理函式
 }
}
void CMenuSimulateOutPut::OnBnClickedSimulateoutputOpen()
{
 CString       strFilters,strFileName;
 VARIANT_BOOL     vb;
 ////讀取XML
 strFilters = _T("XML(*.xml)|*.XML||");
 CFileDialog dlg(TRUE,_T("XML"),_T("1019GX.XML"),OFN_READONLY,strFilters, this);///TRUE為OPEN對話方塊,FALSE為SAVE AS對話方塊
 if(dlg.DoModal()==IDOK){
  FilePathName=dlg.GetPathName();
  strFileName = FilePathName.AllocSysString();
  spDoc.CoCreateInstance(CLSID_DOMDocument);
  spDoc->load(CComVariant(strFileName),&vb);//載入XML檔案
  if (((bool)vb) == TRUE) // success!
  {
   FileIsOpen = true;
   AfxMessageBox(_T("XML檔案開啟成功!"));
   ShellExecute(this->m_hWnd,_T("open"),FilePathName,NULL,NULL,SW_SHOWNORMAL);
   ShowNodes();
  }
  else
  {
   AfxMessageBox(_T("XML檔案打開出錯!"));
   return;
  }
 }
}