这几天做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);
CFileDialog hFileDlg(FALSE,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类型才能包含有属性和子节点 { BSTRbstrName,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; //注意属性也是一个IXMLDOMNospNameNodeMap->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() { longi,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() { longi,&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,SW_SHOWNORMAL); ShowNodes(); } else { AfxMessageBox(_T("XML文件打开出错!")); return; } } }