?? xmlparse.cpp
字號:
// CXMLParse.cpp: implementation of the CXMLParse class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XMLParse.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define XML_SUCCEEDED() SUCCEEDED(m_hResult)
#define XML_FAILED() FAILED(m_hResult)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXMLParse::CXMLParse()
{
ResetVariable();
}
CXMLParse::~CXMLParse()
{
FreeAllResource();
}
//
// 在內(nèi)存中構(gòu)造DOM樹,自動創(chuàng)建處理指令(聲明)節(jié)點(diǎn)<?xml version="1.0"
// encoding="UTF-8"?>,并根據(jù)指定的根元素名稱創(chuàng)建跟元素節(jié)點(diǎn).
// 可以在聲明節(jié)點(diǎn)后加入注釋,不支持DTD節(jié)點(diǎn)創(chuàng)建.
//
BOOL CXMLParse::CreateNewXMLDOM(
LPCTSTR strComment/*=""*/, // 注釋
LPCTSTR strEncoding/*="UTF-8"*/ // 編碼
)
{
//初始化
ResetVariable ();
//創(chuàng)建COM對象實(shí)例
m_hResult = CoCreateInstance(CLSID_DOMDocument40,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2,
(void**)&m_pXMLDOMDoc);
if ( XML_FAILED() ) // 如果COM對象實(shí)例創(chuàng)建失敗
{
AfxMessageBox ( "Create COM object instance failed" );
OutErrorStr ();
ResetNodePtr ( &m_pXMLDOMDoc );
return FALSE;
}
// 創(chuàng)建處理指令(聲明)節(jié)點(diǎn)
BSTR target = _com_util::ConvertStringToBSTR("xml");
CString csHead;
csHead.Format ( "version=\"1.0\" encoding=\"%s\"", strEncoding );
BSTR data = csHead.AllocSysString();
IXMLDOMProcessingInstruction *pi;
m_hResult = m_pXMLDOMDoc->createProcessingInstruction ( target, data, &pi );
if ( XML_FAILED() ) // 創(chuàng)建處理指令(聲明)節(jié)點(diǎn)失敗
{
//釋放內(nèi)存中COM對象實(shí)例
ResetNodePtr ( &m_pXMLDOMDoc );
AfxMessageBox ( "Create node failed" );
return FALSE;
}
// 處理指令(聲明)節(jié)點(diǎn)插入DOM樹
IXMLDOMNode * pTempNode = NULL;
VARIANT vtTemp;
vtTemp.vt= VT_EMPTY;
m_hResult = m_pXMLDOMDoc->insertBefore ( pi, vtTemp, &pTempNode );
if ( XML_FAILED() ) // 處理指令(聲明)節(jié)點(diǎn)插入DOM樹失敗
{
//釋放內(nèi)存中COM對象實(shí)例
ResetNodePtr ( &pTempNode );
ResetNodePtr ( &m_pXMLDOMDoc );
AfxMessageBox ( "Create DOMTree failed" );
return FALSE;
}
HRESULT hrErr1,hrErr2,hrErr3,hrErr4;
// 創(chuàng)建注釋節(jié)點(diǎn)
IXMLDOMComment * pTempComment = NULL;
BSTR tempComment = _com_util::ConvertStringToBSTR(strComment);
hrErr1 = m_pXMLDOMDoc->createComment ( tempComment, &pTempComment );
// 插入注釋節(jié)點(diǎn)到DOM樹
ResetNodePtr ( &pTempNode );
vtTemp.vt= VT_EMPTY;
hrErr2 = m_pXMLDOMDoc->insertBefore ( pTempComment, vtTemp, &pTempNode);
ResetNodePtr ( &pTempComment );
//創(chuàng)建頂層元素節(jié)點(diǎn)
IXMLDOMElement * pTempElement = NULL;
BSTR tempElementName = _com_util::ConvertStringToBSTR ( strTopElementName );
hrErr3 = m_pXMLDOMDoc->createElement ( tempElementName, &pTempElement );
//插入頂層元素節(jié)點(diǎn)到DOM樹
pTempNode = NULL;
vtTemp.vt= VT_EMPTY;
hrErr4 = m_pXMLDOMDoc->insertBefore ( pTempElement, vtTemp, &pTempNode );
ResetNodePtr ( &pTempElement );
if ( (hrErr1 == S_OK) && (hrErr2 == S_OK) && (hrErr3 == S_OK) && (hrErr4 == S_OK) )
{
IXMLDOMElement * pTopElement = NULL;
m_pXMLDOMDoc->get_documentElement ( &pTopElement );
//m_pCurNodeList賦值
m_pXMLDOMDoc->selectNodes(_com_util::ConvertStringToBSTR("*"),
&m_pCurNodeList);
//m_pCurNode 指向根元素節(jié)點(diǎn)
//m_nCurNodeListLength為1
//m_nCurNodeNumber為0
if (m_pCurNodeList != NULL)
{
m_pCurNodeList->get_length(&m_nCurNodeListLength);
m_nCurNodeNumber = 0;
m_pCurNodeList->get_item(m_nCurNodeNumber,&m_pCurNode);
}
//釋放臨時對象
ResetNodePtr ( &pTopElement );
}
else
{
//釋放內(nèi)存中COM對象實(shí)例
ResetNodePtr ( &m_pXMLDOMDoc );
AfxMessageBox ( "Create or insert node failed" );
return FALSE;
}
m_pRootNode = m_pCurNode;
return TRUE;
}
void CXMLParse::OutErrorStr()
{
CString csMsg;
_com_error er( m_hResult );
csMsg.Format ( "MSXML error : %s\n", er.ErrorMessage() );
AfxMessageBox ( csMsg );
}
//
// 將私有變量重設(shè)
//
void CXMLParse::ResetVariable()
{
m_pXMLDOMDoc = NULL;
m_pCurNodeList = NULL;
m_nCurNodeListLength = 0;
m_nCurNodeNumber = 0;
m_pCurNode = NULL;
m_hResult = S_OK;
m_pRootNode = NULL;
m_dwTotalElementNum = 0;
}
void CXMLParse::FreeAllResource()
{
ResetNodePtr ( &m_pCurNode );
ResetNodePtr ( &m_pCurNodeList );
ResetNodePtr ( &m_pXMLDOMDoc );
ResetVariable();
}
/**************************************************************************
* 函數(shù)介紹:將內(nèi)存中的DOM樹內(nèi)容保存到指定XML文件中.
*
* 輸入?yún)?shù):strDestinationFile:要寫入的XML文件的完整路徑名.
* 返回值 :TRUE - 成功
* FALSE - 失敗
***************************************************************************/
BOOL CXMLParse::Save(LPCTSTR strDestinationFile)
{
VARIANT varDestinationFile;
varDestinationFile.vt = VT_BSTR;
varDestinationFile.bstrVal = _com_util::ConvertStringToBSTR(strDestinationFile);
m_hResult = m_pXMLDOMDoc->save(varDestinationFile);
if ( XML_FAILED() )
{
OutErrorStr();
return FALSE;
}
return TRUE;
}
/**************************************************************************
* 函數(shù)介紹:指定XML源文件,在內(nèi)存中構(gòu)造DOM樹,
* 并讀取指定XML文件的內(nèi)容到DOM樹中.如果出錯則把COM對象實(shí)例(DOM樹)
* 釋放并且指向DOM樹的指針賦空.
* 如果XML文件讀取正確
* m_pCurNodeList包含一個節(jié)點(diǎn)即根元素節(jié)點(diǎn)
* m_pCurNode指向根元素節(jié)點(diǎn)
* m_nCurNodeListLength為1
* m_nCurNodeNumber為0
*
* 輸入?yún)?shù):lpszFileOrData - 要讀取的XML文件的完整路徑名,或者是 XML 字符串
**************************************************************************/
BOOL CXMLParse::Load(LPCTSTR lpszFileOrData, BOOL bIsFileName/*=TRUE*/)
{
if ( !lpszFileOrData || strlen(lpszFileOrData) < 1 ) return FALSE;
//初始化
ResetVariable ();
//創(chuàng)建COM對象實(shí)例
m_hResult = CoCreateInstance(CLSID_DOMDocument40,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2,
(void**)&m_pXMLDOMDoc);
// 如果COM對象實(shí)例創(chuàng)建失敗
if ( XML_FAILED() )
{
AfxMessageBox ( "Create COM object instance failed" );
OutErrorStr ();
ResetNodePtr ( &m_pXMLDOMDoc );
return FALSE;
}
// 讀取XML文檔內(nèi)容到內(nèi)存中DOM樹
VARIANT_BOOL *bLoadSuccess = NULL;
if ( bIsFileName )
{
VARIANT varSourceFile;
varSourceFile.vt = VT_BSTR;
varSourceFile.bstrVal = _com_util::ConvertStringToBSTR(lpszFileOrData);
//讀取源文件
//如果有DTD則也進(jìn)行有效性檢查,否則不進(jìn)行有效性檢查
m_hResult = m_pXMLDOMDoc->load(varSourceFile, bLoadSuccess);
}
else
{
m_hResult = m_pXMLDOMDoc->loadXML ( _com_util::ConvertStringToBSTR(lpszFileOrData), bLoadSuccess );
}
// 如果XML文件讀取錯誤(包括良構(gòu)和有效性檢查錯誤)
if ( XML_FAILED() )
{
//釋放內(nèi)存中COM對象實(shí)例
ResetNodePtr ( &m_pXMLDOMDoc );
AfxMessageBox ( "Read XML file failed or file structure invalid" );
return FALSE;
}
//如果XML文件讀取正確
//m_pCurNodeList包含一個節(jié)點(diǎn)即根元素節(jié)點(diǎn)
//m_pCurNode指向根元素節(jié)點(diǎn)
//m_nCurNodeListLength為1
//m_nCurNodeNumber為0
IXMLDOMElement * pTopElement = NULL;
m_pXMLDOMDoc->get_documentElement(&pTopElement);
ResetNodePtr ( &pTopElement );
//m_pCurNodeList賦值
m_pXMLDOMDoc->selectNodes(_com_util::ConvertStringToBSTR("*"),
&m_pCurNodeList);
//m_pCurNode指向根元素節(jié)點(diǎn)
//m_nCurNodeListLength為1
//m_nCurNodeNumber為0
if ( m_pCurNodeList != NULL )
{
m_pCurNodeList->get_length(&m_nCurNodeListLength);
m_nCurNodeNumber = 0;
m_pCurNodeList->get_item(m_nCurNodeNumber,&m_pCurNode);
}
m_pRootNode = m_pCurNode;
return ( m_pRootNode != NULL );
}
/**************************************************************************
* 函數(shù)介紹:在當(dāng)前元素節(jié)點(diǎn)層次中變換當(dāng)前元素節(jié)點(diǎn).在同一節(jié)點(diǎn)鏈表中跳轉(zhuǎn)
* 如果執(zhí)行成功,使m_pCurNode指向當(dāng)前元素節(jié)點(diǎn)鏈表中的指定位置,
* m_nCurNodeNumber為當(dāng)前元素節(jié)點(diǎn)在當(dāng)前元素節(jié)點(diǎn)鏈表中的位置.
*
* 輸入?yún)?shù):curNodeNumber: int類型,指定要選中的元素節(jié)點(diǎn)在當(dāng)前元素節(jié)點(diǎn)鏈
* 表中的位置.
* 返回值: FALSE - 指定的位置越界或者其它執(zhí)行錯誤.
* TRUE: - 執(zhí)行成功.
**************************************************************************/
BOOL CXMLParse::GoTo_ParallelNode(long curNodeNumber)
{
//判斷指定的當(dāng)前元素節(jié)點(diǎn)的位置是否越界
if ((curNodeNumber >= 0) && (curNodeNumber < m_nCurNodeListLength))
{
m_nCurNodeNumber = curNodeNumber;
m_hResult = m_pCurNodeList->get_item(m_nCurNodeNumber, &m_pCurNode);
if ( XML_SUCCEEDED() )
return TRUE;
}
TRACE ( "Invalid function parameter or node position is wrong\n" );
return FALSE;
}
/**************************************************************************
* 函數(shù)介紹:向下變換當(dāng)前元素節(jié)點(diǎn)層次.進(jìn)入子節(jié)點(diǎn)
* 如果當(dāng)前元素節(jié)點(diǎn)有子元素節(jié)點(diǎn)m_pCurNodeList和
* m_nCurNodeListLength賦相應(yīng)值,m_nCurNodeNumber為0,m_pCurNode指
* 向新節(jié)點(diǎn)鏈表的第一個節(jié)點(diǎn).
* 如果當(dāng)前元素節(jié)點(diǎn)沒有子元素節(jié)點(diǎn),保持m_pCurNodeList,
* m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不變.
*
* 返回值 :FALSE: 如果當(dāng)前元素節(jié)點(diǎn)沒有子元素節(jié)點(diǎn)或者其它執(zhí)行錯誤
* TRUE: 如果當(dāng)前元素節(jié)點(diǎn)有子元素節(jié)點(diǎn)
**************************************************************************/
BOOL CXMLParse::GoTo_Child()
{
IXMLDOMNodeList *pTempNodeList = NULL;
m_pCurNode->selectNodes(_com_util::ConvertStringToBSTR("*"),&pTempNodeList);
//判斷當(dāng)前元素節(jié)點(diǎn)是否有子元素節(jié)點(diǎn)
if (pTempNodeList != NULL)
{
m_pCurNode->selectNodes(_com_util::ConvertStringToBSTR("*"),&m_pCurNodeList);
m_pCurNodeList->get_length(&m_nCurNodeListLength);
m_nCurNodeNumber = 0;
if (m_nCurNodeListLength > 0)
{
m_pCurNodeList->get_item(0,&m_pCurNode);
}
ResetNodePtr ( &pTempNodeList );
return TRUE;
}
TRACE ( "Goto child node failed\n" );
return FALSE;
}
//
// 由于 m_pCurNode 改變,所以需要更新其他當(dāng)前變量 m_pCurNodeList,
// m_nCurNodeNumber,m_nCurNodeListLength 的值
//
void CXMLParse::UpdateCurValue ()
{
IXMLDOMNode * pTempNode = NULL;
m_pCurNode->get_parentNode ( &pTempNode );
pTempNode->selectNodes(_com_util::ConvertStringToBSTR("*"),&m_pCurNodeList);
ResetNodePtr ( &pTempNode );
}
/**************************************************************************
* 函數(shù)介紹:向上變換當(dāng)前元素節(jié)點(diǎn)層次.退回到父節(jié)點(diǎn)
* 如果當(dāng)前元素節(jié)點(diǎn)不是頂層元素節(jié)點(diǎn)m_pCurNodeList和
* m_nCurNodeListLength賦相應(yīng)值,m_nCurNodeNumber為0,m_pCurNode指
* 向新節(jié)點(diǎn)鏈表的第一個節(jié)點(diǎn).
* 如果當(dāng)前元素節(jié)點(diǎn)是頂層元素節(jié)點(diǎn),保持m_pCurNodeList,
* m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不變.
*
* 返回值 :FALSE: 如果當(dāng)前元素節(jié)點(diǎn)是頂層元素節(jié)點(diǎn)或者其它執(zhí)行錯誤
* TRUE: 如果當(dāng)前元素節(jié)點(diǎn)不是頂層元素節(jié)點(diǎn)
**************************************************************************/
BOOL CXMLParse::GoTo_Parent()
{
// 取當(dāng)前元素節(jié)點(diǎn)的父節(jié)點(diǎn)
// 通過其父節(jié)點(diǎn)的類型判斷當(dāng)前元素節(jié)點(diǎn)是否為根元素節(jié)點(diǎn)
IXMLDOMNode * pTempNode = NULL;
m_pCurNode->get_parentNode ( &pTempNode );
if ( pTempNode != NULL )
{
BSTR bszTemp;
CString strTemp;
pTempNode->get_nodeTypeString ( &bszTemp );
strTemp = CString(bszTemp);
//如果當(dāng)前元素節(jié)點(diǎn)不是根元素節(jié)點(diǎn)
if ( strTemp.Compare("document") != 0 )
{
m_pCurNode = pTempNode;
m_pCurNode->get_parentNode ( &pTempNode );
pTempNode->selectNodes(_com_util::ConvertStringToBSTR("*"),&m_pCurNodeList);
m_pCurNodeList->get_length(&m_nCurNodeListLength);
m_nCurNodeNumber = 0;
if (m_nCurNodeListLength > 0)
{
m_pCurNodeList->get_item(0,&m_pCurNode);
ResetNodePtr ( &pTempNode );
return TRUE;
}
}
}
ResetNodePtr ( &pTempNode );
return FALSE;
}
/**************************************************************************
* 函數(shù)介紹:退回到根點(diǎn)
* 如果當(dāng)前元素節(jié)點(diǎn)不是頂層元素節(jié)點(diǎn) m_pCurNodeList 和
* m_nCurNodeListLength賦相應(yīng)值,m_nCurNodeNumber 為0, m_pCurNod e指
* 向新節(jié)點(diǎn)鏈表的第一個節(jié)點(diǎn).
* 如果當(dāng)前元素節(jié)點(diǎn)是頂層元素節(jié)點(diǎn),保持 m_pCurNodeList,
* m_nCurNodeListLength ,m_nCurNodeNumber,m_pCurNode值不變.
*
* 返回值 :FALSE: 如果當(dāng)前元素節(jié)點(diǎn)是頂層元素節(jié)點(diǎn)或者其它執(zhí)行錯誤
* TRUE: 如果當(dāng)前元素節(jié)點(diǎn)不是頂層元素節(jié)點(diǎn)
**************************************************************************/
BOOL CXMLParse::GoTo_Root()
{
if ( !m_pRootNode )
return FALSE;
m_pCurNode = m_pRootNode;
UpdateCurValue ();
return TRUE;
}
/**************************************************************************
* 函數(shù)介紹:根據(jù)標(biāo)簽名跳轉(zhuǎn)
* 如果找到標(biāo)簽對應(yīng)的元素,節(jié)點(diǎn)m_pCurNodeList和
* m_nCurNodeListLength 賦相應(yīng)值,m_nCurNodeNumber 為0,m_pCurNode指
* 向新節(jié)點(diǎn)鏈表的第一個節(jié)點(diǎn).
* 如果找不到標(biāo)簽對應(yīng)的元素,保持m_pCurNodeList,
* m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不變.
*
* 返回值 :FALSE: 如果當(dāng)前元素節(jié)點(diǎn)是頂層元素節(jié)點(diǎn)或者其它執(zhí)行錯誤
* TRUE: 如果當(dāng)前元素節(jié)點(diǎn)不是頂層元素節(jié)點(diǎn)
**************************************************************************/
BOOL CXMLParse::GoTo_TagName(LPCTSTR lpszTagName)
{
IXMLDOMNodeList *pTempNodeList = NULL;
m_hResult = m_pXMLDOMDoc->getElementsByTagName (
_com_util::ConvertStringToBSTR(lpszTagName),
&pTempNodeList );
CString csMsg;
if ( XML_FAILED() )
{
csMsg.Format ( "Could not find specify tag : [ %s ]", lpszTagName );
AfxMessageBox ( csMsg );
return FALSE;
}
IXMLDOMNode *pTempNode = NULL;
m_hResult = pTempNodeList->get_item ( 0, &pTempNode );
if ( XML_FAILED() || !pTempNode )
{
csMsg.Format ( "Get item failed. Tag name is : [ %s ]", lpszTagName );
TRACE ( "%s\n", csMsg );
return FALSE;
}
m_pCurNode = pTempNode;
UpdateCurValue ();
return TRUE;
}
/**************************************************************************
* 函數(shù)介紹:刪除當(dāng)前元素節(jié)點(diǎn)的指定屬性.
*
* 輸入?yún)?shù):strAttributeName: CString類型,指明當(dāng)前元素節(jié)點(diǎn)指定屬性的名稱.
* 返回值 :1:執(zhí)行成功.
* 2:執(zhí)行失敗.
**************************************************************************/
BOOL CXMLParse::DelAttribute(LPCTSTR strAttributeName)
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -