这里是利用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",但是不知道在哪一层,那个树下
可以在查找时名字前加个"//"这样就表示在任意一层查找
pRootElem->selectSingleNode(" //Data");
posted on 2011-02-14 14:17
CrackRen 阅读(118)
评论(0) 编辑 收藏 所属分类:
VC