現在,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)即可延伸標記語言 (XML),它與HTML一樣,都是SGML(Standard Generalized Markup Language,標準通用標記語言 (SGML))。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;
}