现在,XML格式字符串广泛应用于各种信息的交互。不论你是做网络开发,还是桌面应用程序开发,甚至是游戏开发,都会不可避免的碰到XML格式的字符串,今天这篇文章来介绍一下在C++语言下,基于COM的XML字符串的解析与生成。
首先这里要明确两个基本概念,一个是COM,一个是XML格式。
先来说COM,COM的全称是Component Object model,组件对象模型,OMG(ObjectManagementGroup)为了实现把复杂的应用程序分割成一个个功能单一,规模较小的组件,来越来越复杂化的程序功能,发布了CORBA(Common Object Request Breaker Architecture)标准,这个标准在unix下执行,而在windows下,这套标准就是COM。详细的说明可以在我的另一篇博文:http://blog.csdn.net/crich_moon/article/details/6614392中找到。
再来简单介绍一下XML,XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。接下来先看一下如何用COM组件实现对XML格式字符串的解析。
首先需要包含头文件
#include <windows.h>
#include <msxml.h>
然后在头文件中定义类,声明类的成员函数:
class XmlHelper
{
public:
XmlHelper(void);
XmlHelper(LPCTSTR XmlFileName);
~XmlHelper(void);
HRESULT ReadItemValue(LPCTSTR strItem,LPCTSTR strValueName,TCHAR* pchValue,DWORD dwCount);
HRESULT ReadItemAttributeValue(LPCTSTR strItem,LPCTSTR strValueName,LPCTSTR strAttributeName,TCHAR* strAttributeValue,DWORD dwCount);
HRESULT WriteItemValue(LPCTSTR strRootName,LPCTSTR strItem,LPCTSTR strValueName,LPCTSTR strValue,LPCTSTR strAttributeName,LPCTSTR strAttributeValue);
private:
BSTR m_szXmlFile;
BSTR m_szXmlStr;
int m_nXmlLen;
};
然后在CPP文件中定义成员函数的实现:
XmlHelper::XmlHelper(LPCTSTR XmlFileName)
{
if (!XmlFileName)
{
ASSERT(0);
}
else
{
m_szXmlFile = SysAllocString(XmlFileName);
}
}
HRESULT XmlHelper::ReadItemValue(LPCTSTR strItem,LPCTSTR strValueName,TCHAR* pchValue,DWORD dwCount)
{
HRESULT hr = E_FAIL;
BSTR pText = NULL;
IXMLDOMDocument* piXMLDoc = NULL;
IXMLDOMElement* pRoot = NULL;
CoCreateInstance(CLSID_DOMDocument,NULL,CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument,(LPVOID*)&piXMLDoc);
if (piXMLDoc)
{
piXMLDoc->put_async(VARIANT_FALSE);
VARIANT vXmlFile;
vXmlFile.vt = VT_BSTR;
vXmlFile.bstrVal = (BSTR)m_szXmlFile;
VARIANT_BOOL vb;
piXMLDoc->load(vXmlFile, &vb);
if (vb)
{
piXMLDoc->get_documentElement(&pRoot);
if (pRoot)
{
IXMLDOMNode* pMainNode = NULL;
IXMLDOMElement* pMainNodeEle = NULL;
pRoot->selectSingleNode((BSTR)strItem,&pMainNode);
if (pMainNode)
{
pMainNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pMainNodeEle);
pMainNode->Release();
}
if (pMainNodeEle)
{
IXMLDOMNode* pValueNode = NULL;
IXMLDOMElement* pValueNodeEle = NULL;
pMainNodeEle->selectSingleNode((BSTR)strValueName,&pValueNode);
if (pValueNode)
{
pValueNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pValueNodeEle);
pValueNode->Release();
}
if (pValueNodeEle)
{
hr = pValueNodeEle->get_text(&pText);
pValueNodeEle->Release();
}
pMainNodeEle->Release();
}
pRoot->Release();
}
}
piXMLDoc->Release();
}
if (pText)
{
wcsncpy(pchValue,pText,dwCount);
SysFreeString(pText);
}
return hr;
}
HRESULT XmlHelper::ReadItemAttributeValue(LPCTSTR strItem,LPCTSTR strValueName,LPCTSTR strAttributeName,TCHAR* strAttributeValue,DWORD dwCount)
{
WaitForSingleObject(m_hSyncEvent,5000);
HRESULT hr = E_FAIL;
VARIANT vattri={0};
IXMLDOMDocument* piXMLDoc = NULL;
IXMLDOMElement* pRoot = NULL;
CoCreateInstance(CLSID_DOMDocument,NULL,CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument,(LPVOID*)&piXMLDoc);
if (piXMLDoc)
{
piXMLDoc->put_async(VARIANT_FALSE);
VARIANT vXmlFile;
vXmlFile.vt = VT_BSTR;
vXmlFile.bstrVal = (BSTR)m_szXmlFile;
VARIANT_BOOL vb;
piXMLDoc->load(vXmlFile, &vb);
if (vb)
{
piXMLDoc->get_documentElement(&pRoot);
if (pRoot)
{
IXMLDOMNode* pMainNode = NULL;
IXMLDOMElement* pMainNodeEle = NULL;
pRoot->selectSingleNode((BSTR)strItem,&pMainNode);
if (pMainNode)
{
pMainNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pMainNodeEle);
pMainNode->Release();
}
if (pMainNodeEle)
{
IXMLDOMNode* pValueNode = NULL;
IXMLDOMElement* pValueNodeEle = NULL;
pMainNodeEle->selectSingleNode((BSTR)strValueName,&pValueNode);
if (pValueNode)
{
pValueNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pValueNodeEle);
pValueNode->Release();
}
if (pValueNodeEle)
{
//hr = pValueNodeEle->get_text(&pText);
BSTR bstrattr = SysAllocString(strAttributeName);
hr = pValueNodeEle->getAttribute(bstrattr,&vattri);
SysFreeString(bstrattr);
pValueNodeEle->Release();
}
pMainNodeEle->Release();
}
pRoot->Release();
}
}
piXMLDoc->Release();
}
if (vattri.vt == VT_BSTR && vattri.bstrVal)
{
wcsncpy(strAttributeValue,vattri.bstrVal,dwCount);
SysFreeString(vattri.bstrVal);
}
SetEvent(m_hSyncEvent);
return hr;
}
HRESULT XmlHelper::WriteItemValue(LPCTSTR strRootName,LPCTSTR strItem,LPCTSTR strValueName,LPCTSTR strValue,LPCTSTR strAttributeName,LPCTSTR strAttributeValue)
{
WaitForSingleObject(m_hSyncEvent,5000);
HRESULT hr = E_FAIL;
IXMLDOMDocument* piXMLDoc = NULL;
IXMLDOMElement* pRoot = NULL;
CoCreateInstance(CLSID_DOMDocument,NULL,CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument,(LPVOID*)&piXMLDoc);
if (piXMLDoc)
{
piXMLDoc->put_async(VARIANT_FALSE);
VARIANT vXmlFile;
vXmlFile.vt = VT_BSTR;
vXmlFile.bstrVal = (BSTR)m_szXmlFile;
VARIANT_BOOL vb;
piXMLDoc->load(vXmlFile, &vb);
if (!vb)
{
piXMLDoc->createElement((BSTR)strRootName,&pRoot);
if (pRoot)
{
piXMLDoc->appendChild(pRoot,NULL);
}
}
if (!pRoot)
{
piXMLDoc->get_documentElement(&pRoot);
}
if (pRoot)
{
IXMLDOMNode* pMainNode = NULL;
IXMLDOMElement* pMainNodeEle = NULL;
pRoot->selectSingleNode((BSTR)strItem,&pMainNode);
if (!pMainNode)
{
piXMLDoc->createElement((BSTR)strItem,&pMainNodeEle);
pRoot->appendChild(pMainNodeEle,NULL);
}
else
{
pMainNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pMainNodeEle);
pMainNode->Release();
}
if (pMainNodeEle)
{
IXMLDOMNode* pValueNode = NULL;
IXMLDOMElement* pValueNodeEle = NULL;
pMainNodeEle->selectSingleNode((BSTR)strValueName,&pValueNode);
if (!pValueNode)
{
piXMLDoc->createElement((BSTR)strValueName,&pValueNodeEle);
pMainNodeEle->appendChild(pValueNodeEle,NULL);
}
else
{
pValueNode->QueryInterface(IID_IXMLDOMElement,(VOID**)&pValueNodeEle);
pValueNode->Release();
}
if (pValueNodeEle)
{
VARIANT vut;
vut.vt = VT_BSTR;
vut.bstrVal = SysAllocString(strAttributeValue);
pValueNodeEle->setAttribute((BSTR)strAttributeName,vut);
SysFreeString(vut.bstrVal);
BSTR bstrValue = SysAllocString(strValue);
hr = pValueNodeEle->put_text(bstrValue);
SysFreeString(bstrValue);
pValueNodeEle->Release();
}
pMainNodeEle->Release();
}
pRoot->Release();
}
piXMLDoc->save(vXmlFile);
piXMLDoc->Release();
}
SetEvent(m_hSyncEvent);
return hr;
}