⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparse.cpp

📁 sMS 通讯 可免费发手机短信 我之前好好做的工作
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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();
}

//
// 在内存中构造DOM树,自动创建处理指令(声明)节点<?xml version="1.0" 
// encoding="UTF-8"?>,并根据指定的根元素名称创建跟元素节点.
// 可以在声明节点后加入注释,不支持DTD节点创建.
//
BOOL CXMLParse::CreateNewXMLDOM(
		LPCTSTR strTopElementName,			// 根元素名
		LPCTSTR strComment/*=""*/,			// 注释
		LPCTSTR strEncoding/*="UTF-8"*/		// 编码
)
{
	//初始化
	ResetVariable ();

	//创建COM对象实例
	m_hResult = CoCreateInstance(CLSID_DOMDocument40,
		                     NULL,
			   			     CLSCTX_INPROC_SERVER, 
		                     IID_IXMLDOMDocument2,
						     (void**)&m_pXMLDOMDoc);
	
	if ( XML_FAILED() )	// 如果COM对象实例创建失败
	{
		AfxMessageBox ( "Create COM object instance failed" );
		OutErrorStr ();
		ResetNodePtr ( &m_pXMLDOMDoc );
		return FALSE;
	}

	// 创建处理指令(声明)节点
	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() )	// 创建处理指令(声明)节点失败
	{
		//释放内存中COM对象实例
		ResetNodePtr ( &m_pXMLDOMDoc );
		AfxMessageBox ( "Create node failed" );
		return FALSE;
	}

	// 处理指令(声明)节点插入DOM树
	IXMLDOMNode * pTempNode = NULL;
	VARIANT vtTemp;
	vtTemp.vt= VT_EMPTY;
	m_hResult = m_pXMLDOMDoc->insertBefore ( pi, vtTemp, &pTempNode );
	
	if ( XML_FAILED() )	// 处理指令(声明)节点插入DOM树失败
	{
		//释放内存中COM对象实例
		ResetNodePtr ( &pTempNode );
		ResetNodePtr ( &m_pXMLDOMDoc );
		AfxMessageBox ( "Create DOMTree failed" );
		return FALSE;
	}
	
	HRESULT hrErr1,hrErr2,hrErr3,hrErr4;		
	// 创建注释节点
	IXMLDOMComment * pTempComment = NULL;
	BSTR tempComment = _com_util::ConvertStringToBSTR(strComment);
	hrErr1 = m_pXMLDOMDoc->createComment ( tempComment, &pTempComment );
	
	// 插入注释节点到DOM树
	ResetNodePtr ( &pTempNode );
	vtTemp.vt= VT_EMPTY;
	hrErr2 = m_pXMLDOMDoc->insertBefore ( pTempComment, vtTemp, &pTempNode);
	ResetNodePtr ( &pTempComment );
	
	//创建顶层元素节点
	IXMLDOMElement * pTempElement = NULL;
	BSTR tempElementName = _com_util::ConvertStringToBSTR ( strTopElementName );
	hrErr3 = m_pXMLDOMDoc->createElement ( tempElementName, &pTempElement );
	
	//插入顶层元素节点到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 指向根元素节点
		//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
	{
		//释放内存中COM对象实例
		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 );
}

//
// 将私有变量重设
//
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();
}

/**************************************************************************
* 函数介绍:将内存中的DOM树内容保存到指定XML文件中.
*
* 输入参数: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;
}
/**************************************************************************
* 函数介绍:指定XML源文件,在内存中构造DOM树,
*           并读取指定XML文件的内容到DOM树中.如果出错则把COM对象实例(DOM树)
*           释放并且指向DOM树的指针赋空.
*           如果XML文件读取正确
*		    m_pCurNodeList包含一个节点即根元素节点
*		    m_pCurNode指向根元素节点
*		    m_nCurNodeListLength为1
*		    m_nCurNodeNumber为0
*
* 输入参数:lpszFileOrData	-	要读取的XML文件的完整路径名,或者是 XML 字符串
**************************************************************************/
BOOL CXMLParse::Load(LPCTSTR lpszFileOrData, BOOL bIsFileName/*=TRUE*/)
{
	if ( !lpszFileOrData || strlen(lpszFileOrData) < 1 ) return FALSE;
	//初始化
	ResetVariable ();
	
	//创建COM对象实例
	m_hResult = CoCreateInstance(CLSID_DOMDocument40,
		NULL,
		CLSCTX_INPROC_SERVER, 
		IID_IXMLDOMDocument2,
		(void**)&m_pXMLDOMDoc);
	
	// 如果COM对象实例创建失败
	if ( XML_FAILED() )
	{
		AfxMessageBox ( "Create COM object instance failed" );
		OutErrorStr ();
		ResetNodePtr ( &m_pXMLDOMDoc );
		return FALSE;
	}
	
	// 读取XML文档内容到内存中DOM树
	VARIANT_BOOL *bLoadSuccess = NULL;
	if ( bIsFileName )
	{
		VARIANT varSourceFile;
		varSourceFile.vt = VT_BSTR; 
		varSourceFile.bstrVal = _com_util::ConvertStringToBSTR(lpszFileOrData);
		
		//读取源文件
		//如果有DTD则也进行有效性检查,否则不进行有效性检查
		m_hResult = m_pXMLDOMDoc->load(varSourceFile, bLoadSuccess);
	}
	else
	{
		m_hResult = m_pXMLDOMDoc->loadXML ( _com_util::ConvertStringToBSTR(lpszFileOrData), bLoadSuccess );
	}
	
	// 如果XML文件读取错误(包括良构和有效性检查错误)
	if ( XML_FAILED() )	
	{
		//释放内存中COM对象实例
		ResetNodePtr ( &m_pXMLDOMDoc );		
		AfxMessageBox ( "Read XML file failed or file structure invalid" );
		return FALSE;
	}
	
	//如果XML文件读取正确
	//m_pCurNodeList包含一个节点即根元素节点
	//m_pCurNode指向根元素节点
	//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指向根元素节点
	//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 );
}

/**************************************************************************
* 函数介绍:在当前元素节点层次中变换当前元素节点.在同一节点链表中跳转
*           如果执行成功,使m_pCurNode指向当前元素节点链表中的指定位置,
*           m_nCurNodeNumber为当前元素节点在当前元素节点链表中的位置. 
*
* 输入参数:curNodeNumber: int类型,指定要选中的元素节点在当前元素节点链
*                          表中的位置.
* 返回值:	FALSE		-	指定的位置越界或者其它执行错误.
*			TRUE:		-	执行成功.
**************************************************************************/
BOOL CXMLParse::GoTo_ParallelNode(long curNodeNumber)
{
	//判断指定的当前元素节点的位置是否越界
	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;
}
/**************************************************************************
* 函数介绍:向下变换当前元素节点层次.进入子节点
*           如果当前元素节点有子元素节点m_pCurNodeList和
*           m_nCurNodeListLength赋相应值,m_nCurNodeNumber为0,m_pCurNode指
*			向新节点链表的第一个节点.
*			如果当前元素节点没有子元素节点,保持m_pCurNodeList,
*			m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不变.
*
* 返回值  :FALSE: 如果当前元素节点没有子元素节点或者其它执行错误
*           TRUE: 如果当前元素节点有子元素节点
**************************************************************************/
BOOL CXMLParse::GoTo_Child()
{
	IXMLDOMNodeList *pTempNodeList = NULL;
	m_pCurNode->selectNodes(_com_util::ConvertStringToBSTR("*"),&pTempNodeList);

	//判断当前元素节点是否有子元素节点
	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 改变,所以需要更新其他当前变量 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 );
}

/**************************************************************************
* 函数介绍:向上变换当前元素节点层次.退回到父节点
*           如果当前元素节点不是顶层元素节点m_pCurNodeList和
*           m_nCurNodeListLength赋相应值,m_nCurNodeNumber为0,m_pCurNode指
*			向新节点链表的第一个节点.
*			如果当前元素节点是顶层元素节点,保持m_pCurNodeList,
*			m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不变.
*
* 返回值  :FALSE: 如果当前元素节点是顶层元素节点或者其它执行错误
*           TRUE: 如果当前元素节点不是顶层元素节点
**************************************************************************/
BOOL CXMLParse::GoTo_Parent()
{
	// 取当前元素节点的父节点
	// 通过其父节点的类型判断当前元素节点是否为根元素节点
	IXMLDOMNode * pTempNode = NULL;
	m_pCurNode->get_parentNode ( &pTempNode );
	if ( pTempNode != NULL )
	{
		BSTR bszTemp;
		CString strTemp;
		pTempNode->get_nodeTypeString ( &bszTemp );
		strTemp = CString(bszTemp);

		//如果当前元素节点不是根元素节点
		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;
}

/**************************************************************************
* 函数介绍:退回到根点
*           如果当前元素节点不是顶层元素节点 m_pCurNodeList 和
*           m_nCurNodeListLength赋相应值,m_nCurNodeNumber 为0, m_pCurNod e指
*			向新节点链表的第一个节点.
*			如果当前元素节点是顶层元素节点,保持 m_pCurNodeList,
*			m_nCurNodeListLength ,m_nCurNodeNumber,m_pCurNode值不变.
*
* 返回值  :FALSE: 如果当前元素节点是顶层元素节点或者其它执行错误
*           TRUE: 如果当前元素节点不是顶层元素节点
**************************************************************************/
BOOL CXMLParse::GoTo_Root()
{
	if ( !m_pRootNode )
		return FALSE;

	m_pCurNode = m_pRootNode;
	UpdateCurValue ();
	return TRUE;
}

/**************************************************************************
* 函数介绍:根据标签名跳转
*           如果找到标签对应的元素,节点m_pCurNodeList和
*           m_nCurNodeListLength 赋相应值,m_nCurNodeNumber 为0,m_pCurNode指
*			向新节点链表的第一个节点.
*			如果找不到标签对应的元素,保持m_pCurNodeList,
*			m_nCurNodeListLength,m_nCurNodeNumber,m_pCurNode值不变.
*
* 返回值  :FALSE: 如果当前元素节点是顶层元素节点或者其它执行错误
*           TRUE: 如果当前元素节点不是顶层元素节点
**************************************************************************/
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;
}
/**************************************************************************
* 函数介绍:删除当前元素节点的指定属性.
*
* 输入参数:strAttributeName: CString类型,指明当前元素节点指定属性的名称.
* 返回值  :1:执行成功.
*           2:执行失败.   
**************************************************************************/
BOOL CXMLParse::DelAttribute(LPCTSTR strAttributeName)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -